/**
* Splits a blob address into three parts: the schema, the ID, and parameters/flags.
*
+ * @since 1.33
+ *
* @param string $address
*
* @throws InvalidArgumentException
* @return array [ $schema, $id, $parameters ], with $parameters being an assoc array.
*/
- private static function splitBlobAddress( $address ) {
+ public static function splitBlobAddress( $address ) {
if ( !preg_match( '/^(\w+):(\w+)(\?(.*))?$/', $address, $m ) ) {
throw new InvalidArgumentException( "Bad blob address: $address" );
}
$cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
$rows = $cache->getWithSetCallback(
// Page protections always leave a new null revision
- $cache->makeKey( 'page-restrictions', $id, $this->getLatestRevID() ),
+ $cache->makeKey( 'page-restrictions', 'v1', $id, $this->getLatestRevID() ),
$cache::TTL_DAY,
function ( $curValue, &$ttl, array &$setOpts ) use ( $loadRestrictionsFromDb ) {
$dbr = wfGetDB( DB_REPLICA );
$setOpts += Database::getCacheSetOptions( $dbr );
+ $lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
+ if ( $lb->hasOrMadeRecentMasterChanges() ) {
+ // @TODO: cleanup Title cache and caller assumption mess in general
+ $ttl = WANObjectCache::TTL_UNCACHEABLE;
+ }
return $loadRestrictionsFromDb( $dbr );
}
if ( $this->fld_ids ) {
$vals['pageid'] = (int)$row->rev_page;
$vals['revid'] = (int)$row->rev_id;
- // $vals['textid'] = (int)$row->rev_text_id; // todo: Should this field be exposed?
if ( !is_null( $row->rev_parent_id ) ) {
$vals['parentid'] = (int)$row->rev_parent_id;
"LordMsz",
"Dvorapa",
"Matěj Suchánek",
- "Ilimanaq29"
+ "Ilimanaq29",
+ "Patriccck"
]
},
"apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|Dokumentace]]\n* [[mw:Special:MyLanguage/API:FAQ|Otázky a odpovědi]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api E-mailová konference]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Oznámení k API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Chyby a požadavky]\n</div>\n<strong>Stav:</strong> Všechny funkce uvedené na této stránce by měly fungovat, ale API se stále aktivně vyvíjí a může se kdykoli změnit. Upozornění na změny získáte přihlášením se k [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ e-mailové konferenci mediawiki-api-announce].\n\n<strong>Chybné požadavky:</strong> Pokud jsou do API zaslány chybné požadavky, bude vrácena HTTP hlavička s klíčem „MediaWiki-API-Error“ a hodnota této hlavičky a chybový kód budou nastaveny na stejnou hodnotu. Více informací najdete [[mw:Special:MyLanguage/API:Errors_and_warnings|v dokumentaci]].\n\n<p class=\"mw-apisandbox-link\"><strong>Testování:</strong> Pro jednoduché testování požadavků na API zkuste [[Special:ApiSandbox]].</p>",
"apierror-blocked": "Byla vám zablokována možnost editace.",
"apierror-mustbeloggedin": "Abyste mohli $1, musíte být přihlášeni.",
"apierror-nosuchsection-what": "$2 neobsahuje sekci $1.",
+ "apierror-readonly": "Wiki je právě v módu pro čtení a nelze ji editovat.",
"apierror-sectionsnotsupported-what": "$1 nepodporuje sekce.",
"apierror-timeout": "Server neodpověděl v očekávaném čase.",
"api-credits-header": "Zásluhy",
/**
* Process cache of loaded messages that are defined in MediaWiki namespace
*
- * @var MapCacheLRU Map of (language code => key => " <MESSAGE>" or "!TOO BIG")
+ * @var MapCacheLRU Map of (language code => key => " <MESSAGE>" or "!TOO BIG" or "!ERROR")
*/
protected $cache;
}
// Set the text for small software-defined messages in the main cache map
+ $revisionStore = MediaWikiServices::getInstance()->getRevisionStore();
+ $revQuery = $revisionStore->getQueryInfo( [ 'page', 'user' ] );
$res = $dbr->select(
- [ 'page', 'revision', 'text' ],
- [ 'page_title', 'page_latest', 'old_id', 'old_text', 'old_flags' ],
+ $revQuery['tables'],
+ $revQuery['fields'],
array_merge( $conds, [ 'page_len <= ' . intval( $wgMaxMsgCacheEntrySize ) ] ),
__METHOD__ . "($code)-small",
[],
- [
- 'revision' => [ 'JOIN', 'page_latest=rev_id' ],
- 'text' => [ 'JOIN', 'rev_text_id=old_id' ],
- ]
+ $revQuery['joins']
);
foreach ( $res as $row ) {
$name = $this->contLang->lcfirst( $row->page_title );
// Include entries/stubs for all keys in $mostused in adaptive mode
if ( $wgAdaptiveMessageCache || $this->isMainCacheable( $name, $overridable ) ) {
- $text = Revision::getRevisionText( $row );
- if ( $text === false ) {
- // Failed to fetch data; possible ES errors?
- // Store a marker to fetch on-demand as a workaround...
- // TODO Use a differnt marker
- $entry = '!TOO BIG';
+ try {
+ $rev = $revisionStore->newRevisionFromRow( $row );
+ $content = $rev->getContent( MediaWiki\Revision\SlotRecord::MAIN );
+ $text = $this->getMessageTextFromContent( $content );
+ } catch ( Exception $ex ) {
+ $text = false;
+ }
+
+ if ( !is_string( $text ) ) {
+ $entry = '!ERROR';
wfDebugLog(
'MessageCache',
__METHOD__
if ( $entry !== null ) {
// Message page exists as an override of a software messages
if ( substr( $entry, 0, 1 ) === ' ' ) {
- // The message exists and is not '!TOO BIG'
+ // The message exists and is not '!TOO BIG' or '!ERROR'
return (string)substr( $entry, 1 );
} elseif ( $entry === '!NONEXISTENT' ) {
// The text might be '-' or missing due to some data loss
}
$revOpts = [ 'page' ];
- if ( $this->text != self::STUB ) {
- // TODO: remove the text and make XmlDumpWriter use a RevisionStore instead! (T198706)
- $revOpts[] = 'text';
- }
+
$revQuery = Revision::getQueryInfo( $revOpts );
// We want page primary rather than revision
];
unset( $join['page'] );
- // TODO: remove rev_text_id and make XmlDumpWriter use a RevisionStore instead! (T198706)
- $fields = array_merge( $revQuery['fields'], [ 'page_restrictions, rev_text_id' ] );
+ $fields = $revQuery['fields'];
+ $fields[] = 'page_restrictions';
+
+ if ( $this->text != self::STUB ) {
+ $fields['_load_content'] = '1';
+ }
$conds = [];
if ( $cond !== '' ) {
*
* @file
*/
-
use MediaWiki\MediaWikiServices;
+use MediaWiki\Revision\RevisionStore;
+use MediaWiki\Storage\SqlBlobStore;
/**
* @ingroup Dump
*/
class XmlDumpWriter {
+
+ /**
+ * Title of the currently processed page
+ *
+ * @var Title|null
+ */
+ private $currentTitle = null;
+
/**
* Opens the XML output stream's root "<mediawiki>" element.
* This does not include an xml directive, so is safe to include
*/
public function openPage( $row ) {
$out = " <page>\n";
- $title = Title::makeTitle( $row->page_namespace, $row->page_title );
- $out .= ' ' . Xml::elementClean( 'title', [], self::canonicalTitle( $title ) ) . "\n";
+ $this->currentTitle = Title::makeTitle( $row->page_namespace, $row->page_title );
+ $canonicalTitle = self::canonicalTitle( $this->currentTitle );
+ $out .= ' ' . Xml::elementClean( 'title', [], $canonicalTitle ) . "\n";
$out .= ' ' . Xml::element( 'ns', [], strval( $row->page_namespace ) ) . "\n";
$out .= ' ' . Xml::element( 'id', [], strval( $row->page_id ) ) . "\n";
if ( $row->page_is_redirect ) {
- $page = WikiPage::factory( $title );
+ $page = WikiPage::factory( $this->currentTitle );
$redirect = $page->getRedirectTarget();
if ( $redirect instanceof Title && $redirect->isValidRedirectTarget() ) {
$out .= ' ';
strval( $row->page_restrictions ) ) . "\n";
}
- Hooks::run( 'XmlDumpWriterOpenPage', [ $this, &$out, $row, $title ] );
+ Hooks::run( 'XmlDumpWriterOpenPage', [ $this, &$out, $row, $this->currentTitle ] );
return $out;
}
return " </page>\n";
}
+ /**
+ * @return RevisionStore
+ */
+ private function getRevisionStore() {
+ return MediaWikiServices::getInstance()->getRevisionStore();
+ }
+
+ /**
+ * @return SqlBlobStore
+ */
+ private function getBlobStore() {
+ return MediaWikiServices::getInstance()->getBlobStore();
+ }
+
/**
* Dumps a "<revision>" section on the output stream, with
* data filled in from the given database row.
}
}
+ // TODO: rev_content_model no longer exists with MCR, see T174031
if ( isset( $row->rev_content_model ) && !is_null( $row->rev_content_model ) ) {
$content_model = strval( $row->rev_content_model );
} else {
// probably using $wgContentHandlerUseDB = false;
- $title = Title::makeTitle( $row->page_namespace, $row->page_title );
- $content_model = ContentHandler::getDefaultModelFor( $title );
+ $content_model = ContentHandler::getDefaultModelFor( $this->currentTitle );
}
$content_handler = ContentHandler::getForModelID( $content_model );
+ // TODO: rev_content_format no longer exists with MCR, see T174031
if ( isset( $row->rev_content_format ) && !is_null( $row->rev_content_format ) ) {
$content_format = strval( $row->rev_content_format );
} else {
$out .= " " . Xml::elementClean( 'text',
[ 'xml:space' => 'preserve', 'bytes' => intval( $row->rev_len ) ],
strval( $text ) ) . "\n";
- } else {
- // Stub output
+ } elseif ( isset( $row->_load_content ) ) {
+ // TODO: make this fully MCR aware, see T174031
+ $rev = $this->getRevisionStore()->newRevisionFromRow( $row, 0, $this->currentTitle );
+ $slot = $rev->getSlot( 'main' );
+ $content = $slot->getContent();
+
+ if ( $content instanceof TextContent ) {
+ // HACK: For text based models, bypass the serialization step.
+ // This allows extensions (like Flow)that use incompatible combinations
+ // of serialization format and content model.
+ $text = $content->getNativeData();
+ } else {
+ $text = $content->serialize( $content_format );
+ }
+
+ $text = $content_handler->exportTransform( $text, $content_format );
+ $out .= " " . Xml::elementClean( 'text',
+ [ 'xml:space' => 'preserve', 'bytes' => intval( $slot->getSize() ) ],
+ strval( $text ) ) . "\n";
+ } elseif ( isset( $row->rev_text_id ) ) {
+ // Stub output for pre-MCR schema
+ // TODO: MCR: rev_text_id only exists in the pre-MCR schema. Remove this when
+ // we drop support for the old schema.
$out .= " " . Xml::element( 'text',
[ 'id' => $row->rev_text_id, 'bytes' => intval( $row->rev_len ) ],
"" ) . "\n";
+ } else {
+ // Backwards-compatible stub output for MCR aware schema
+ // TODO: MCR: emit content addresses instead of text ids, see T174031, T199121
+ $rev = $this->getRevisionStore()->newRevisionFromRow( $row, 0, $this->currentTitle );
+ $slot = $rev->getSlot( 'main' );
+
+ // Note that this is currently the ONLY reason we have a BlobStore here at all.
+ // When removing this line, check whether the BlobStore has become unused.
+ $textId = $this->getBlobStore()->getTextIdFromAddress( $slot->getAddress() );
+ $out .= " " . Xml::element( 'text',
+ [ 'id' => $textId, 'bytes' => intval( $slot->getSize() ) ],
+ "" ) . "\n";
}
if ( isset( $row->rev_sha1 )
$tableClass = $this->getTableClass();
$ret = Html::openElement( 'table', [
- 'class' => "mw-datatable $tableClass" ]
+ 'class' => " $tableClass" ]
);
$ret .= Html::rawElement( 'thead', [], Html::rawElement( 'tr', [], "\n" . $s . "\n" ) );
$ret .= Html::openElement( 'tbody' ) . "\n";
}
/**
+ * TablePager relies on `mw-datatable` for styling, see T214208
* @return string
*/
protected function getTableClass() {
- return 'TablePager';
+ return 'mw-datatable';
}
/**
] );
if ( $shouldSetCookie ) {
$block->setCookie( $this->getRequest()->response() );
-
- // temporary measure the use of cookies on ip blocks
- $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
- $stats->increment( 'block.ipblock.setCookie.success' );
}
} elseif ( $this->isLoggedIn() && $config->get( 'CookieSetOnAutoblock' ) ) {
$shouldSetCookie = $block->getType() === Block::TYPE_USER && $block->isAutoblocking();
"apisandbox-sending-request": "Изпращане на API заявка...",
"apisandbox-loading-results": "Получаване на API резултати...",
"apisandbox-request-selectformat-label": "Показване на заявката с данни като:",
- "apisandbox-request-format-url-label": "URL низ на запитването",
+ "apisandbox-request-format-url-label": "URL-низ на заявката",
"apisandbox-request-url-label": "URL-адрес на заявката:",
"apisandbox-request-format-json-label": "JSON",
"apisandbox-request-json-label": "JSON заявка:",
"trackingcategories-desc": "Критерий за включване на категория",
"restricted-displaytitle-ignored": "Страници с игнорирани заглавия за показване",
"restricted-displaytitle-ignored-desc": "Страницата съдържа игнориран <code><nowiki>{{DISPLAYTITLE}}</nowiki></code>, защото той не съвпада с действителното заглавие на страницата.",
- "noindex-category-desc": "СÑ\82Ñ\80аниÑ\86аÑ\82а не Ñ\81е индекÑ\81иÑ\80а оÑ\82 Ñ\80обоÑ\82и, заÑ\89оÑ\82о Ñ\81Ñ\8aдÑ\8aÑ\80жа вÑ\8aлÑ\88ебнаÑ\82а дÑ\83миÑ\87ка <code><nowiki>__NOINDEX__</nowiki></code> и е в именно пÑ\80оÑ\81Ñ\82Ñ\80анÑ\81Ñ\82во, кÑ\8aдето такова отбелязване е позволено.",
- "index-category-desc": "СÑ\82Ñ\80аниÑ\86аÑ\82а Ñ\81Ñ\8aдÑ\8aÑ\80жа <code><nowiki>__INDEX__</nowiki></code> (и е в именно пÑ\80оÑ\81Ñ\82Ñ\80анÑ\81Ñ\82во, кÑ\8aдето такова отбелязване е позволено), поради което се индексира от роботи, където обикновено не би била индексирана.",
+ "noindex-category-desc": "СÑ\82Ñ\80аниÑ\86аÑ\82а не Ñ\81е индекÑ\81иÑ\80а оÑ\82 Ñ\80обоÑ\82и, заÑ\89оÑ\82о Ñ\81Ñ\8aдÑ\8aÑ\80жа вÑ\8aлÑ\88ебнаÑ\82а дÑ\83миÑ\87ка <code><nowiki>__NOINDEX__</nowiki></code> и е оÑ\82 именно пÑ\80оÑ\81Ñ\82Ñ\80анÑ\81Ñ\82во, в което такова отбелязване е позволено.",
+ "index-category-desc": "СÑ\82Ñ\80аниÑ\86аÑ\82а Ñ\81Ñ\8aдÑ\8aÑ\80жа <code><nowiki>__INDEX__</nowiki></code> (и е оÑ\82 именно пÑ\80оÑ\81Ñ\82Ñ\80анÑ\81Ñ\82во, в което такова отбелязване е позволено), поради което се индексира от роботи, където обикновено не би била индексирана.",
"post-expand-template-inclusion-category-desc": "Страницата е по-голяма от <code>$wgMaxArticleSize</code> след разгръщането на всички шаблони, поради което някои шаблони не са разгърнати.",
- "post-expand-template-argument-category-desc": "Страницата е по-голяма от <code>$wgMaxArticleSize</code> след разгръщането на аргументите на шаблона (нещо в тройни къдрави скоби, например <code>{{{Foo}}}</code>).",
+ "post-expand-template-argument-category-desc": "Страницата е по-голяма от <code>$wgMaxArticleSize</code> след разгръщането на аргументите на шаблона (нещо в тройни фигурни скоби, например <code>{{{Foo}}}</code>).",
"expensive-parserfunction-category-desc": "Страницата използва твърде много ресурсоемки анализиращи функции (като <code>#ifexist</code>). Вижте [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgExpensiveParserFunctionLimit Manual:$wgExpensiveParserFunctionLimit].",
"broken-file-category-desc": "Страницата съдържа повредена препратка към файл (препратка за поставяне на файл, когато такъв не съществува).",
"hidden-category-category-desc": "Категорията съдържа <code><nowiki>__HIDDENCAT__</nowiki></code>, което предотвратява показването ѝ в страниците по подразбиране.",
"revertpage": "Премахване на [[Special:Contributions/$2|редакции на $2]] ([[User talk:$2|беседа]]); възвръщане към последната версия на [[User:$1|$1]]",
"revertpage-nouser": "Връщане на редакции на скрит потребител до последната версия на [[User:$1|$1]]",
"rollback-success": "Отменени редакции на {{GENDER:$3|$1}};\nвъзвръщане към последната версия на {{GENDER:$4|$2}}.",
- "rollback-success-notify": "Премахнати редакции на $1; възвръщане към последна версия на $2. [$3 Показване на промени]",
+ "rollback-success-notify": "Премахнати редакции на $1;\nвръщане към последна версия на $2. [$3 Показване на промени]",
"sessionfailure-title": "Прекъсната сесия",
"sessionfailure": "Изглежда има проблем със сесията ви;\nдействието беше отказано като предпазна мярка срещу крадене на сесията.\nМоля, изпратете формуляра повторно.",
"changecontentmodel": "Промяна на модела на съдържанието на страница",
"namespace": "Именно пространство:",
"invert": "Обръщане на избора",
"tooltip-invert": "Поставянето на отметка ще скрие всички промени в страниците от избраното именно пространство (и свързаните именни пространства)",
- "tooltip-whatlinkshere-invert": "Отбелязване на полето, за да скриете препратките от страниците в избраното именно пространство.",
+ "tooltip-whatlinkshere-invert": "Отбележете полето, за да скриете препратки от страници от избраното именно пространство.",
"namespace_association": "Свързани именни пространства",
"tooltip-namespace_association": "Поставянето на отметка ще включи и беседите и именните пространства, свързани с избраното именно пространство.",
"blanknamespace": "(Основно)",
"logentry-suppress-block": "$1 $3ی بۆ ماوەی $5 $6 بەربەست کرد",
"logentry-suppress-reblock": "$1 ھەڵبژاردەکانی بەربەستنی $3ی گۆڕی بە ماوەی بەسەرچوونی $5 $6",
"logentry-import-upload": "$1 {{GENDER:$2|بارکرد}} $3 بە بەکارھێنانی [[special:Import|بارکەر]]",
+ "logentry-import-interwiki": "$1 $3ی لە ویکییەکی ترەوە ھاوردەکرد",
"logentry-import-interwiki-details": "$1 $3ی لە $5ەوە ھەناردە کرد ($4 بەسەرداچوونەوە)",
"logentry-move-move": "$1 پەڕەی $3ی {{GENDER:$2|گواستەوە}} بۆ $4",
"logentry-move-move-noredirect": "$1 پەڕەی $3ی بە بێ بەجێھشتنی ڕەوانەکەرێک {{GENDER:$2|گواستەوە}} بۆ $4",
"log-action-filter-block": "جۆری بلۆک:",
"log-action-filter-contentmodel": "جۆری گۆڕینی مۆدێلی ناوەڕۆک:",
"log-action-filter-delete": "جۆری سڕینەوە:",
+ "log-action-filter-import": "جۆری ھاوردن:",
"log-action-filter-all": "ھەموو",
"log-action-filter-block-block": "بەربەستن",
"log-action-filter-block-unblock": "ھەڵگرتنی بەربەستن",
"tog-enotifminoredits": "Auch bei kleinen Änderungen an Seiten und Dateien E-Mails senden",
"tog-enotifrevealaddr": "Meine E-Mail-Adresse in Benachrichtigungs-E-Mails anzeigen",
"tog-shownumberswatching": "Anzahl der beobachtenden Benutzer anzeigen",
- "tog-oldsig": "Die vorhandene Signatur:",
+ "tog-oldsig": "Die genutzte Signatur:",
"tog-fancysig": "Signatur als Wikitext behandeln (ohne automatische Verlinkung)",
"tog-uselivepreview": "Vorschau ohne Neuladen der Seite anzeigen",
"tog-forceeditsummary": "Warnen, sofern beim Speichern die Zusammenfassung fehlt",
"exif-rowsperstrip": "Number of rows per strip",
"exif-stripbytecounts": "Bytes per compressed strip",
"exif-jpeginterchangeformat": "Offset to JPEG SOI",
- "exif-jpeginterchangeformatlength": "Bytes of JPEG data",
+ "exif-jpeginterchangeformatlength": "JPEG verilerinin baytı",
"exif-whitepoint": "Beyaz nokta kromatiği",
"exif-primarychromaticities": "Chromaticities of primarities",
"exif-ycbcrcoefficients": "Renk aralığı dönüştürme matris katsayısı",
"Amirsara",
"Physicsch",
"Nbi",
- "Amjad Khan"
+ "Amjad Khan",
+ "Ahmad252"
]
},
"tog-underline": "خط کشیدن زیر پیوندها:",
"subject-preview": "پیشنمایش موضوع:",
"previewerrortext": "در زمان تلاش برای نمایش دادن تغییرات شما، خطایی رخ داد.",
"blockedtitle": "کاربر بسته شدهاست",
+ "blockedtext-partial": "<strong>حساب کاربری یا آدرس آیپی شما از انجام تغییرات در این صفحه منع شدهاست. شما همچنان میتوانید در دیگر صفحههای این ویکی ویرایش کنید.</strong> برای مشاهده جزئیات کامل قطع دسترسی به [[ویژه:مشارکتهای من|مشارکتهای حساب]] مراجعه کنید.\n\nاین قطع دسترسی توسط $1 انجام گرفتهاست.\n\nدلیل قطع دسترسی <em>$2</em> است.\n\n* زمان آغاز قطع دسترسی: $8\n* زمان پایان قطع دسترسی: $6\n* موارد مورد نظر: $7\n* شناسه قطع دسترسی: #$5",
"blockedtext": "<strong>دسترسی حساب کاربری یا نشانی آیپی شما بسته شدهاست.</strong>\n\nاین قطع دسترسی توسط $1 انجام شده است.\nدلیل ارائهشده چنین است: <em>$2</em>\n\n* شروع قطع دسترسی: $8\n* پایان قطع دسترسی: $6\n* کاربری هدف قطع دسترسی: $7\n\nشما میتوانید با $1 یا [[{{MediaWiki:Grouppage-sysop}}|مدیری]] دیگر تماس بگیرید و در این باره صحبت کنید.\nتوجه کنید که شما نمیتوانید از قابلیت «{{int:emailuser}}» استفاده کنید مگر آنکه آدرس ایمیل معتبری در [[Special:Preferences|ترجیحات کاربری]] خودتان ثبت کرده باشید و نیز باید امکان استفاده از این قابلیت برای شما قطع نشده باشد.\nنشانی آیپی فعلی شما $3 و شمارهٔ قطع دسترسی شما $5 است.\nلطفاً تمامی جزئیات فوق را در کلیهٔ درخواستهایی که در این باره مطرح میکنید ذکر کنید.",
"autoblockedtext": "دسترسی نشانی آیپی شما قطع شدهاست، زیرا این نشانی آیپی توسط کاربر دیگری استفاده شده که دسترسی او توسط $1 قطع شدهاست.\nدلیل ارائهشده چنین است:\n\n:''$2''\n\n* شروع قطع دسترسی: $8\n* پایان قطع دسترسی: $6\n* کاربری هدف قطع دسترسی: $7\n\nشما میتوانید با $1 یا [[{{MediaWiki:Grouppage-sysop}}|مدیری]] دیگر تماس بگیرید و در این باره صحبت کنید.\nتوجه کنید که شما نمیتوانید از قابلیت «{{int:emailuser}}» استفاده کنید مگر آنکه نشانی ایمیل معتبری در [[Special:Preferences|ترجیحات کاربری]] خودتان ثبت کرده باشید و نیز باید امکان استفاده از این قابلیت برای شما قطع نشده باشد.\nنشانی آیپی فعلی شما $3 و شمارهٔ قطع دسترسی شما $5 است.\nلطفاً تمامی جزئیات فوق را در کلیهٔ درخواستهایی که در این باره مطرح میکنید ذکر کنید.",
"systemblockedtext": "نام کاربری یا نشانی آیپی شما خودکار توسط مدیاویکی مسدود شدهاست.\nدلیل ارائهشده:\n\n:<em>$2</em>\n\n* آغاز بلاک: $8\n* پایان بلاک: $6\n* قطع دسترسیشده مورد نظر: $7\n\nنشانی آیپی کنونی شما $3 است.\nخواهشمند است تمام جزئیات بالا را در هر پرسوجویی که انجام میدهید قرار دهید.",
"ipb-disableusertalk": "ویرایش صفحهً بحث توسط خود کاربر",
"ipb-change-block": "بستن دوبارهٔ کاربر با این تنظیمها",
"ipb-confirm": "تأیید بستن",
- "ipb-partial": "جزئی",
+ "ipb-sitewide": "کلی",
+ "ipb-partial": "موردی",
+ "ipb-sitewide-help": "هر صفحهای در ویکی و تمام فعالیتهای مشارکتی دیگر",
+ "ipb-partial-help": "صفحات خاص یا فضاهای نامی",
"ipb-pages-label": "صفحات",
"ipb-namespaces-label": "فضاهای نام",
"badipaddress": "نشانی آیپی نامعتبر",
]
},
"tog-underline": "Keppelings ûnderstreekje:",
- "tog-hideminor": "Tekstwizigings wei litte út 'Koartlyn feroare'",
+ "tog-hideminor": "Feroarings fan lytse betsjutting ferbergje yn Koartlyn feroare",
"tog-hidepatrolled": "Markearre feroarings ferskûlje yn resinte feroarings",
"tog-newpageshidepatrolled": "Markearre siden ferskûlje yn 'e list mei nije siden",
"tog-extendwatchlist": "Wreidzje folchlist út om alle wizigings sjen te litten, net allinnich de lêste wizigings",
"tog-watchdefault": "Sides dy't jo feroare hawwe folgje",
"tog-watchmoves": "Siden dy't jo werneamd hawwe folgje",
"tog-watchdeletion": "Siden dy't jo wiske hawwe folgje",
- "tog-minordefault": "Feroarings yn it earst oanjaan as tekstwizigings.",
+ "tog-minordefault": "Markearje alle feroarings standert as fan lytse betsjutting",
"tog-previewontop": "By it neisjen, bewurkingsfjild ûnderoan sette",
"tog-previewonfirst": "Lit foarbyld sjen by earste wiziging",
"tog-enotifwatchlistpages": "E-mail my as in side op myn folchlist feroare is.",
"tog-enotifusertalkpages": "E-mail my as myn oerlisside feroare wurdt",
- "tog-enotifminoredits": "E-mail my ek by lytse feroarings fan siden op myn folchlist",
+ "tog-enotifminoredits": "E-mail my ek by feroarings fan lytse betsjutting oan siden en bestannen",
"tog-enotifrevealaddr": "Myn e-mailadres sjen litte yn e-mailberjochten",
"tog-shownumberswatching": "It tal meidoggers sjen litte dat dizze side folget",
"tog-oldsig": "Aktuele sinjatuerprintallyk:",
"tog-forceeditsummary": "Warskôgje at ik de gearfetting leech lit.",
"tog-watchlisthideown": "Eigen bewurkings op myn folchlist ferbergje",
"tog-watchlisthidebots": "Lit gjin bot wizigings sjen yn de folchlist",
- "tog-watchlisthideminor": "Lit gjin tekstwizigings sjen yn de folchlist",
+ "tog-watchlisthideminor": "Feroarings fan lytse betsjutting ferbergje yn de folchlist",
"tog-watchlisthideliu": "Bewurkings fan oanmelde meidoggers op myn folchlist ferbergje",
"tog-watchlisthideanons": "Bewurkings fa anonyme meidoggers op myn folchlist ferbergje",
"tog-watchlisthidepatrolled": "Markearre feroarings op myn folchlist ferskûlje",
"hr_tip": "Horizontale line (mei ferdrach brûke)",
"summary": "Gearfetting:",
"subject": "Underwerp:",
- "minoredit": "Dit is in tekstwiziging",
+ "minoredit": "Dit is fan lytse betsjutting",
"watchthis": "Folgje dizze side",
"savearticle": "Side bewarje",
"publishpage": "Side fêstlizze",
"anontalkpagetext": "----\n<em>Dit is de oerlisside fan in ûnbekende meidogger; in meidogger dy't him/har net oanmeld hat.</em>\nOm't der gjin namme bekend is, wurdt it ynternet-adres brûkt om oan te jaan om wa't it giet.\nMar faak is it sa dat sa'n adres net altyd troch deselde persoan brûkt wurdt.\nAs jo it idee hawwe dat jo as ûnbekende meidogger opmerkings foar in oar krije, dan kinne jo jo [[Special:CreateAccount|registrearje]], of jo [[Special:UserLogin|oanmelde]]. Fan in oanmelde meidogger is it ynternet-adres net sichtber, en as oanmelde meidogger krije jo allinnich opmerkings dy't foar josels bedoeld binne.",
"noarticletext": "Der stjit noch gjin tekst op dizze side. Jo kinne\n[[Special:Search/{{PAGENAME}}|hjirboppe nei dy tekst sykje]], of [{{fullurl:{{FULLPAGENAME}}|action=edit}} de side skriuwe].",
"userpage-userdoesnotexist": "Jo bewurkje in meidoggerside fan in meidogger dy't net bestiet (meidogger \"<nowiki>$1</nowiki>\").\nKontrolearje oft jo dizze side wol oanmeitsje/bewurkje wolle.",
- "userpage-userdoesnotexist-view": "Meidochakkount \"$1\" bestiet net.",
+ "userpage-userdoesnotexist-view": "It meidochakkount \"$1\" bestiet net.",
"clearyourcache": "<strong>Opmerking:</strong> Nei it fêstlizzen kin it nedich wêze de oerslach fan dyn blêder te leegjen foardat de wizigings te sjen binne.\n* <strong>Firefox / Safari:</strong> Hâld <em>Shift</em> yntreaun wylst jo op <em>Dizze side fernije</em> klikke, of typ <em>Ctrl-F5</em> of <em>Ctrl-R</em> (<em>⌘-R</em> op in Mac)\n* <strong>Google Chrome:</strong> Typ <em>CTRL-Shift-R</em> (<em>⌘-Shift-R</em> op in Mac)\n* <strong>Internet Explorer:</strong> Hâld <em>Ctrl</em> yntreaun wylst jo <em>Vernieuwen'' klikke of typ <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Leegje jo cache yn <em>Extra → Voorkeuren</em>",
"usercssyoucanpreview": "<strong>Tip:</strong> Brûk de knop \"{{int:showpreview}}\" om jo nije CSS te testen foar it fêstlizzen.",
"userjsyoucanpreview": "<strong>Tip:</strong> Brûk de knop \"{{int:showpreview}}\" om jo nije JS te testen foar it fêstlizzen.",
"last": "foarige",
"page_first": "earste",
"page_last": "lêste",
- "histlegend": "Utlis: (no) = ferskil mei de side sa't dy no is,\n(doe) = ferskill mei de side sa't er doe wie, foar de feroaring, T = Tekstwiziging",
+ "histlegend": "Ferskil oanjaan: Markearje de rûntsjes fan 'e te ferlykjen ferzjes, en druk op Enter of de knop ûnderoan.<br />\nLeginda: <strong>({{int:cur}})</strong> = ferskil mei de lêste ferzje, <strong>({{int:last}})</strong> = ferskil mei de eardere ferzje, <strong>{{int:minoreditletter}}</strong> = lytse feroaring.",
"history-fieldset-title": "Troch skiednis blêdzje",
"histfirst": "âldste",
"histlast": "nijste",
"right-createpage": "Siden oanmeitsjen (net oerlissiden)",
"right-createtalk": "Oerlissiden oanmeitsjen",
"right-createaccount": "Nije meidoggers oanmeitsje",
- "right-minoredit": "Bydragen markearje as tekstwiziging",
+ "right-minoredit": "Feroarings as fan lytse betsjutting markearje",
"right-move": "Siden werneamen",
"right-move-subpages": "Siden ynklusyf har subsiden ferpleatse.",
"right-move-rootuserpages": "Meidoggersiden fan it heechste nivo in oare namme jaan",
"right-purge": "De cache foar in side leegje sûnder befêstiging",
"right-autoconfirmed": "Hat gjin op IP-adres basearre tiidsôfhinklike beheinings",
"right-bot": "Behannele wurde as in automatisearre proses",
- "right-nominornewtalk": "Lytse bewurkings oan in oerlisside liede net ta in melding 'nije berjochten'",
+ "right-nominornewtalk": "Feroarings fan lytse betsjutting oan in oerlisside liede net ta in melding 'nije berjochten'",
"right-apihighlimits": "Hegere limiten yn API-sykopdrachten brûke",
"right-writeapi": "Bewurkje fia API",
"right-delete": "Siden wiskje",
"action-createpage": "siden oan te meitsjen",
"action-createtalk": "oerlissiden oan te meitsjen",
"action-createaccount": "oanmeitsjen fan dit meidochakkount",
- "action-minoredit": "dizze bewurking as lyts te markearjen",
+ "action-minoredit": "dizze feroaring as fan lytse betsjutting te markearjen",
"action-move": "dizze side in oare namme te jaan",
"action-move-subpages": "dizze side en de derby hearrende subsiden in oare namme te jaan",
"action-move-rootuserpages": "meidoggersiden fan it heechste nivo in oare namme te jaan",
"rcfilters-legend-heading": "<strong>List fan ôfkoartings:</strong>",
"rcnotefrom": "Dit binne de feroarings sûnt <b>$2</b> (maksimaal <b>$1</b>).",
"rclistfrom": "Jou nije feroarings, begjinnende mei $3 $2",
- "rcshowhideminor": "$1 tekstwizigings",
+ "rcshowhideminor": "lytse feroarings $1",
"rcshowhideminor-show": "werjaan",
"rcshowhideminor-hide": "ferbergje",
"rcshowhidebots": "bots $1",
"tooltip-ca-nstab-template": "Sjabloan sjen litte",
"tooltip-ca-nstab-help": "Helpside sjen litte",
"tooltip-ca-nstab-category": "Kategory-side sjen litte",
- "tooltip-minoredit": "Markearje dit as in lytse feroaring",
+ "tooltip-minoredit": "Markearje dizze feroaring as fan lytse betsjutting",
"tooltip-save": "Jo feroarings bewarje",
"tooltip-preview": "Oerlêze foar't de side fêstlein is!",
"tooltip-diff": "Sjen litte hokker feroarings jo yn'e tekst makke hawwe.",
"htmlform-cloner-delete": "Fuortsmite",
"revdelete-restricted": "hat beheinings oplein oan behearders",
"revdelete-unrestricted": "hat beheinings foar behearders goedmakke",
- "logentry-newusers-create": "Meidochakkount $1 is {{GENDER:$2|oanmakke}}",
- "logentry-newusers-autocreate": "Meidochakkount $1 is automatysk {{GENDER:$2|oanmakke}}",
+ "logentry-newusers-create": "It meidochakkount $1 is {{GENDER:$2|oanmakke}}",
+ "logentry-newusers-autocreate": "It meidochakkount $1 is automatysk {{GENDER:$2|oanmakke}}",
"logentry-upload-upload": "$1 hat $3 {{GENDER:$2|opladen}}",
"logentry-upload-overwrite": "$1 hat in nije ferzje fan $3 {{GENDER:$2|opladen}}",
"rightsnone": "(gjin)",
"Tavleen",
"Jayantanth",
"Gopalindians",
- "Prong$31"
+ "Prong$31",
+ "Eisheeta"
]
},
"tog-underline": "कड़ी रेखांकित:",
"tog-norollbackdiff": "सम्पादन वापस लेने के बाद अन्तर न दिखायें",
"tog-useeditwarning": "जब मैं किसी सम्पादन पृष्ठ को बिना बदलावों को बिना सहेजे छोड़ूँ तो मुझे सूचित करें।",
"tog-prefershttps": "सत्र आरम्भ करते समय सदैव सुरक्षित कनेक्शन का प्रयोग करें",
+ "tog-showrollbackconfirmation": "रोलबैक लिंक पर क्लिक करते समय एक पुष्टिकरण संकेत दिखाएं",
"underline-always": "सदैव",
"underline-never": "कभी नहीं",
"underline-default": "त्वचा या प्राथमिक ब्राउज़र",
"badretype": "आपने जो कूटशब्द दिये हैं वे एक दूसरे से नहीं मिलते। फिर से लिखें।",
"usernameinprogress": "इस प्रयोक्ता का खाता निर्माण अभी चालू है।\nकृपया प्रतीक्षा करें।",
"userexists": "आपका दिया सदस्यनाम पहले से प्रयोग में है।\nकृपया कोई अन्य सदस्यनाम चुनें।",
+ "createacct-normalization": "आपका उपयोगकर्ता नाम तकनीकी प्रतिबंधों के कारण \"$2\" में समायोजित किया जाएगा।",
"loginerror": "लॉग इन त्रुटि",
"createacct-error": "खाता निर्माण त्रुटि",
"createaccounterror": "खाता नहीं बन पाया: $1",
"log-action-filter-suppress-reblock": "पुन: ब्लॉक द्वारा युजर अवरोध",
"log-action-filter-upload-upload": "नया अपलोड",
"log-action-filter-upload-overwrite": "फिर से अपलोड",
+ "log-action-filter-upload-revert": "पूर्ववत करें",
"authmanager-authn-not-in-progress": "प्रमाणीकरण प्रगति में नहीं है या सत्र डेटा खो गया है। कृपया शुरुआत से फिर से शुरू करें",
"authmanager-authn-no-primary": "आपूर्ति किए गए क्रेडेंशियल्स को प्रमाणित नहीं किया जा सका।",
"authmanager-authn-no-local-user": "दिए गए क्रेडेंशियल इस विकी पर किसी भी उपयोगकर्ता से जुड़े नहीं हैं।",
"february": "Саь-кур ''(февраль)''",
"march": "Мутт-хьал",
"april": "Тушол",
- "may_long": "Села ''(май)''",
+ "may_long": "села",
"june": "Этинга ''(июнь)''",
"july": "Баьцамеа",
"august": "Мяцхали",
"february-gen": "Саь-кур ''(февраль)'' бетта",
"march-gen": "Мутт-хьал",
"april-gen": "Тушол",
- "may-gen": "Села ''(май)'' бетта",
+ "may-gen": "Села",
"june-gen": "Этинга ''(июнь)'' бетта",
"july-gen": "Баьцамеа",
"august-gen": "Мяцхали",
"feb": "Саь-кур ''(фев)''",
"mar": "мутт-хьал",
"apr": "Tушоли",
- "may": "Села ''(май)''",
+ "may": "села",
"jun": "Этинга ''(июн)''",
"jul": "Баьцамеа",
"aug": "Мяцхали",
"february-date": "Саь-кур ''(февраль)'' $1",
"march-date": "Мутт-хьал $1",
"april-date": "Тушол $1",
- "may-date": "Села ''(май)'' $1",
+ "may-date": "Села $1",
"june-date": "Этинга ''(июнь)'' $1",
"july-date": "Баьцамеа $1",
"august-date": "Мяцхали $1",
"namespacesall": "деррига",
"monthsall": "деррига",
"confirm-purge-title": "Укх оагIон кэш ӀоцIенъе",
- "confirm_purge_button": "Мега",
+ "confirm_purge_button": "Мег",
"confirm-purge-top": "Укх оагӀон кэш ӀоцIенъйой?",
"confirm-purge-bottom": "Кэш ӀоцӀенъячул тӀехьагIа оагIон тӀехьара эрш хьахьокхаргья.",
"imgmultipagenext": "тӀехьайоагӀа оагӀув →",
"filereadonlyerror": "نأبوٙە جانیا \"$1\" نە آلئشت کاری بأکیت سی یە کئ ئمایە جا \"$2\" ئیسئ ها د حال و بال حأنئن.\n\nدیڤوٙنداری کئ ڤئ نە قولف کئردە ها د حال و بال گوتە دیاری \"$3\" .",
"invalidtitle-knownnamespace": "داسوٙن نادیار سی نوم جا \"$2\" و نیسئسە \"$3\"",
"invalidtitle-unknownnamespace": "داسوٙن نادیار سی شومارە نادیار نوم جا \"$2\" و نیسئسە \"$3\"",
- "exception-nologin": "Ù\87Ù±Ù\86Û\8c Ù\86Û\8cÙ\88مایتٱ ڤامیٛن",
+ "exception-nologin": "Ù\87Ù\86Û\8c Ù\86Û\8fمایتٱ ڤامیٛن",
"exception-nologin-text": "لوطف بأکیت بیایت ڤامین سی یە کئ د ئی بألگە یا کونئشتکاری دأسرئسی داشتوٙییت.",
"exception-nologin-text-manual": "لوطف بأکیت ڤئ $1 صئلا بئیتوٙ کئ د ئی بألگە یا کونئشتکاری دأسرئسی داشتوٙە.",
"virus-badscanner": "سازڤارە گأن:ڤیروٙس نادیار:<em>$1</em>",
"nav-login-createaccount": " ڤامین ئوٙمائن/راس کئردئن حئساڤ",
"logout": "د ساموٙنە دئرئوٙمائن",
"userlogout": "د ساموٙنە دئرئوٙمائن",
- "notloggedin": "Ù\87Ù±Ù\86Û\8c Ù\86Û\8cÙ\88مایتٱ ڤامیٛن",
+ "notloggedin": "Ù\87Ù\86Û\8c Ù\86Û\8fمایتٱ ڤامیٛن",
"userlogin-noaccount": "یاٛ هساو نارؽت؟",
"userlogin-joinproject": "ٱندوم دؽارگٱ {{SITENAME}} بۊئؽت",
"createaccount": "هساو دۏرس بٱکؽت",
"uploadbtn": "سوڤار کئردئن جانیا",
"reuploaddesc": "سوار کردن نه انجوم شیو بکیت و د ورئردیت جابلگ سوارکرد",
"upload-tryagain": "کل کردن توضیحیا آلشت دئیه بیه جانیا",
- "uploadnologin": "Ù\87Ù±Ù\86Û\8c Ù\86Û\8cÙ\88مایتٱ ڤامیٛن",
+ "uploadnologin": "Ù\87Ù\86Û\8c Ù\86Û\8fمایتٱ ڤامیٛن",
"uploadnologintext": "لطفن $1 سی سوارکرد جانیایا.",
"upload_directory_missing": "نشونگه سوارکرد ($1) وجود ناره و نبوئه دروسش بکی.",
"upload_directory_read_only": "نشونگه سوارکرد($1) د لا سرور قاول نیسنن نئ.",
"watchlistfor2": "سی $1 $2",
"nowatchlist": "شما هیچی د سیل برگ خوتو ناریت",
"watchlistanontext": "لطفن بیایت وامین و ویرایشتیا نه د سیل برگتو سیل بکیت.",
- "watchnologin": "Ù\87Ù±Ù\86Û\8c Ù\86Û\8cÙ\88مایتٱ ڤامیٛن",
+ "watchnologin": "Ù\87Ù\86Û\8c Ù\86Û\8fمایتٱ ڤامیٛن",
"addwatch": "ئضاف کئردئن د سئیل بأرگ",
"addedwatchtext": "بألگە «[[:$1]]» د [[Special:Watchlist|سئیل بأرگ]] شوما ئضاف بی.\nآلئشتیا ئی بألگە د بألگە چأک چئنە ری ڤئ ریشت د نئھاتئر د ئیچئ نومگە کاری با.",
"addedwatchtext-short": "بلگه \"$1\" وه سیل برگ شما اضاف بیه.",
"logentry-delete-delete_redir": "$1 pervadindamas {{GENDER:$2|ištrynė}} buvusį nukreipimą $3",
"logentry-delete-restore": "$1 atkūrė puslapį $3 ($4)",
"logentry-delete-restore-nocount": "$1 {{GENDER:$2|atkūrė}} puslapį $3",
- "restore-count-revisions": "{{PLURAL:$1|1 versija|versijų: $1}}",
+ "restore-count-revisions": "{{PLURAL:$1|$1 versija|$1 versijos|$1 versijų}}",
"restore-count-files": "{{PLURAL:$1|1 failas|$1 failai}}",
"logentry-delete-event": "$1 {{GENDER:$2|pakeitė}} matomumą {{PLURAL:$5|žurnalo įvykio|$5 žurnalo įvykių}} $3: $4",
"logentry-delete-revision": "$1 {{GENDER:$2|pakeitė}} matomumą {{PLURAL:$5|versijos|$5 versijų}} puslapyje $3: $4",
"log-action-filter-move-move": "Преместување без запис врз пренасочувања",
"log-action-filter-move-move_redir": "Преместување со запис врз пренасочувања",
"log-action-filter-newusers-create": "Создавање од анонимен корисник",
- "log-action-filter-newusers-create2": "Создавање од анонимен корисник",
+ "log-action-filter-newusers-create2": "Создавање од регистриран корисник",
"log-action-filter-newusers-autocreate": "Автоматско создавање",
"log-action-filter-newusers-byemail": "Создавање со лозинка испратена по е-пошта",
"log-action-filter-patrol-patrol": "Рачна патрола",
"tog-useeditwarning": "സേവ് ചെയ്യാത്ത മാറ്റങ്ങളോടു കൂടിയ തിരുത്തൽ താളിൽ നിന്നും പോകുമ്പോൾ എന്നെ അറിയിക്കുക",
"tog-prefershttps": "പ്രവേശിച്ചിരിക്കുമ്പോൾ എപ്പോഴും സുരക്ഷിതമായ കണൿഷൻ ഉപയോഗിക്കുക",
"tog-showrollbackconfirmation": "തിരിച്ചാക്കാനുള്ള കണ്ണി ഞെക്കുമ്പോൾ, അത് സ്ഥിരീകരിക്കാനുള്ള ചോദ്യം പ്രദർശിപ്പിക്കുക",
- "underline-always": "എല്ലായ്പ്പോഴും",
+ "underline-always": "എല്ലായ്പ്പോഴും",
"underline-never": "ഒരിക്കലും അരുത്",
"underline-default": "ദൃശ്യരൂപത്തിൽ അഥവാ ബ്രൗസറിൽ സ്വതേയുള്ള സ്വഭാവം",
"editfont-style": "തിരുത്തൽ മേഖലയിലെ ഫോണ്ടിന്റെ ശൈലി:",
"uploadstash-errclear": "പ്രമാണങ്ങൾ ശൂന്യമാക്കൽ പരാജയപ്പെട്ടു.",
"uploadstash-refresh": "പ്രമാണങ്ങളുടെ പട്ടിക പുതുക്കുക",
"uploadstash-thumbnail": "ലഘുചിത്രം കാണുക",
+ "uploadstash-bad-path-invalid": "പാത്ത് അസാധുവാണ്.",
"uploadstash-bad-path-unknown-type": "അപരിചിതമായ തരം \"$1\".",
"uploadstash-file-not-found-no-thumb": "ലഘുചിത്രം സംഘടിപ്പിക്കാൻ കഴിഞ്ഞില്ല.",
"uploadstash-file-not-found-no-remote-thumb": "ലഘുചിത്രം എടുക്കൽ പരാജയപ്പെട്ടു: $1\nയു.ആർ.എൽ.= $2",
"uploadstash-no-extension": "എക്സ്റ്റെൻഷൻ ശൂന്യമാണ്.",
+ "uploadstash-zero-length": "പ്രമാണത്തിന്റെ നീളം ശൂന്യമാണ്.",
"img-auth-accessdenied": "പ്രവേശനമില്ല",
"img-auth-nopathinfo": "പാത്ത് വിവരങ്ങൾ ലഭ്യമല്ല.\nതാങ്കളുടെ സെർവർ REQUEST_URI ഒപ്പം/അല്ലെങ്കിൽ PATH_INFO കൈമാറ്റം ചെയ്യാൻ കഴിയുന്നതായി സജ്ജീകരിച്ചിരിക്കേണ്ടതുണ്ട്.\nഅങ്ങനെ ചെയ്തിട്ടുണ്ടെങ്കിൽ $wgUsePathInfo സജ്ജമാക്കുക.\nhttps://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization കാണുക.",
"img-auth-notindir": "ആവശ്യപ്പെട്ട പാത അപ്ലോഡ് ഡയറക്റ്ററിയിൽ സജ്ജീകരിച്ചു നൽകിയിട്ടില്ല.",
"apisandbox-submit-invalid-fields-title": "ചില മണ്ഡലങ്ങൾ അസാധുവാണ്",
"apisandbox-results": "ഫലങ്ങൾ",
"apisandbox-request-url-label": "അഭ്യർത്ഥനാ യൂ.ആർ.എൽ.:",
+ "apisandbox-request-json-label": "JSON നുവേണ്ടി അപേക്ഷിക്കുക:",
"apisandbox-request-time": "അഭ്യർത്ഥനയുടെ സമയം: {{PLURAL:$1|$1 മി.സെ.}}",
"apisandbox-results-fixtoken": "ചീട്ട് ശരിയാക്കിയ ശേഷം വീണ്ടും സമർപ്പിക്കുക",
+ "apisandbox-results-fixtoken-fail": "\"$1\" ടോക്കൻ എടുക്കുന്നത് പരാജയപെട്ടു.",
+ "apisandbox-alert-page": "ഈ താളിലെ ഫീൽഡുകൾ അസാധുവാണ്.",
"apisandbox-continue": "തുടരുക",
"apisandbox-continue-clear": "ശൂന്യമാക്കുക",
"apisandbox-multivalue-all-namespaces": "$1 (എല്ലാ നാമമേഖലകളും)",
"booksources-search": "തിരയുക",
"booksources-text": "പുതിയതും ഉപയോഗിച്ചതുമായ പുസ്തകങ്ങൾ വിൽക്കുന്ന സൈറ്റുകളിലേക്കുള്ള ലിങ്കുകളുടെ പട്ടിക ആണ് താഴെ. താങ്കൾ തിരയുന്ന പുസ്തകത്തെ പറ്റിയുള്ള കൂടുതൽ വിവരങ്ങൾ ഈ പട്ടികയിൽ നിന്നു ലഭിച്ചേക്കാം:",
"booksources-invalid-isbn": "തന്നിരിക്കുന്ന ഐ.എസ്.ബി.എൻ. സാധുവാണെന്നു തോന്നുന്നില്ല; യഥാർത്ഥ സ്രോതസ്സിൽ നിന്നും പകർത്തിയപ്പോൾ തെറ്റുപറ്റിയോ എന്നു പരിശോധിക്കുക",
+ "magiclink-tracking-rfc": "RFC മാജിക് കണ്ണികൾ ഉപയോഗിക്കുന്ന താളുകൾ",
+ "magiclink-tracking-pmid": "PMID മാജിക് കണ്ണികൾ ഉപയോഗിക്കുന്ന താളുകൾ",
+ "magiclink-tracking-isbn": "ISBN മാജിക് കണ്ണികൾ ഉപയോഗിക്കുന്ന താളുകൾ",
"specialloguserlabel": "നടപ്പിലാക്കിയയാൾ:",
"speciallogtitlelabel": "ലക്ഷ്യം (തലക്കെട്ട് അല്ലെങ്കിൽ ഉപയോക്താവിനെ തിരയാനുള്ള {{ns:user}}:ഉപയോക്തൃനാമം) :",
"log": "പ്രവർത്തനരേഖകൾ",
"htmlform-date-invalid": "താങ്കൾ നൽകിയ വില തീയതിയായി കണക്കാക്കാനാകുന്നില്ല. വവവവ-മാമാ-തീതീ ഘടന ഉപയോഗിച്ചുനോക്കുക",
"htmlform-time-invalid": "താങ്കൾ നൽകിയ വില സമയമായി കണക്കാക്കാനാകുന്നില്ല. മമ:മിമി:സെസെ ഘടന ഉപയോഗിച്ചുനോക്കുക",
"htmlform-datetime-invalid": "താങ്കൾ നൽകിയ വില തീയതിയും സമയവുമായി കണക്കാക്കാനാകുന്നില്ല. വവവവ-മാമാ-തീതീ മമ:മിമി:സെസെ ഘടന ഉപയോഗിച്ചുനോക്കുക",
+ "htmlform-date-toohigh": "$1 എന്ന അനുവദനീയമായ തിയതിക്ക് ശേഷമുള്ളതാണ് താങ്കൾ കൊടുത്തിരിക്കുന്ന തീയതി.",
+ "htmlform-time-toolow": "$1 എന്ന അനുവദനീയമായ തിയതിക്ക് മുൻപുള്ള തീയതിയാണ് താങ്കൾ കൊടുത്തിരിക്കുന്നത്.",
"htmlform-title-badnamespace": "[[:$1]] ഉള്ളത് \"{{ns:$2}}\" നാമമേഖലയിലല്ല.",
"htmlform-title-not-creatable": "\"$1\" സൃഷ്ടിക്കാനാവുന്ന തലക്കെട്ടല്ല.",
"htmlform-title-not-exists": "$1 നിലവിലില്ല.",
"authmanager-provider-password": "രഹസ്യവാക്ക്-അധിഷ്ഠിത സാധൂകരണം",
"authmanager-provider-password-domain": "രഹസ്യവാക്ക്-ഡൊമൈൻ-അധിഷ്ഠിത സാധൂകരണം",
"authmanager-provider-temporarypassword": "താത്കാലിക രഹസ്യവാക്ക്",
+ "authprovider-confirmlink-success-line": "$1: വിജയകരമായി ലിങ്ക് ചെയ്തു.",
"authprovider-resetpass-skip-label": "മറികടക്കുക",
+ "authform-newtoken": "ടോക്കൺ കാണുന്നില്ല. $1",
+ "authform-notoken": "ടോക്കൺ കാണുന്നില്ല",
+ "authform-wrongtoken": "തെറ്റായ ടോക്കൻ",
"specialpage-securitylevel-not-allowed-title": "അനുവദിച്ചിട്ടില്ല",
"specialpage-securitylevel-not-allowed": "താങ്കളുടെ വ്യക്തിത്വം പരിശോധിക്കാൻ കഴിയാഞ്ഞതിനാൽ ഈ താൾ ഉപയോഗിക്കാൻ താങ്കളെ അനുവദിക്കാനാവില്ല.",
"authpage-cannot-login": "പ്രവേശനം തുടങ്ങാൻ സാധിക്കുന്നില്ല.",
"limitreport-unstrip-size": "Unstrip veličina nakon proširenja",
"limitreport-unstrip-size-value": "$1/$2 {{PLURAL:$2|bajt|bajta|bajtova}}",
"expandtemplates": "Proširi šablone",
- "expand_templates_input": "Unos - Унос",
+ "expand_templates_title": "Naslov konteksta, za {{FULLPAGENAME}} itd.:",
+ "expand_templates_input": "Ulazni wikitekst:",
+ "expand_templates_output": "Izvod",
+ "expand_templates_xml_output": "XML izlaz",
+ "expand_templates_html_output": "Sirov HTML-izlaz",
+ "expand_templates_ok": "U redu",
+ "expand_templates_remove_comments": "Ukloni komentare",
+ "expand_templates_remove_nowiki": "Pritaji <nowiki> oznake u ishodu",
+ "expand_templates_generate_xml": "Prikaži XML stablo za raščlanjivanje",
+ "expand_templates_generate_rawhtml": "Prikazivaj neobrađeni HTML",
"expand_templates_preview": "Pregled",
- "mw-widgets-abandonedit": "Da li ste sigurni da želite napustiti mod uređivanja prije nego što snimite?",
- "mw-widgets-abandonedit-discard": "Odbaci izmjene",
+ "expand_templates_input_missing": "Morate unjeti neki wikitekst.",
+ "pagelanguage": "Promena jezika stranice",
+ "pagelang-name": "Stranica",
+ "pagelang-language": "Jezik",
+ "pagelang-use-default": "Koristi podrazumijevani jezik",
+ "pagelang-select-lang": "Odaberite jezik",
+ "pagelang-reason": "Razlog",
+ "pagelang-submit": "Pošalji",
+ "pagelang-nonexistent-page": "Stranica $1 ne postoji.",
+ "pagelang-unchanged-language": "Stranica $1 već je namjestena na jezik $2.",
+ "pagelang-unchanged-language-default": "Stranica $1 već je namjestena na matični sadržajni jezik wikija.",
+ "pagelang-db-failed": "Baza podataka nije uspjela smijeniti sadržajni jezik.",
+ "right-pagelang": "Mijenjanje jezika stranice",
+ "action-pagelang": "mijenjanje jezika stranice",
+ "log-name-pagelang": "Evidencija mijenjanja jezika",
+ "log-description-pagelang": "Ovo je evidencija promjena jezika stranica.",
+ "logentry-pagelang-pagelang": "$1 {{GENDER:$2|smijenio je|smijenila je}} jezik stranice $3 iz $4 u $5.",
+ "default-skin-not-found": "Nažalost, predodređena tema vašeg wikija ddefinirana u <code dir=\"ltr\">$wgDefaultSkin</code> kao <code>$1</code> nije dostupna.\n\nVaša uspostava sadrži {{PLURAL:$4|sljedeću temu|sljedeće teme}}. Pogledajte [https://www.mediawiki.org/wiki/Manual:Skin_configuration Priručnik: Podešavanje tema] da biste saznali kako ih uključiti i kako odabrati osnovnu.\n\n$2\n\n; Ako ste upravo uspostavili MediaWiki:\n: Vjerovatno ste je uspostavili sa gita, ili pak neposredno sa izvornog koda koristeći se nekom drugom metodom. Ovo je za očekivati. Pokušajte uspostaviti neku temu sa [https://www.mediawiki.org/wiki/Category:All_skins kataloga tema] tako što ćete:\n:* Sa preuzimanjem [https://www.mediawiki.org/wiki/Download tarball-uspostavljača], koji sami sadrži nekoliko tema i proširenja. Možete prekopirati folder <code>skins/</code> iz njega.\n:* Preuzimanje tarball-i za teme sa [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org]. \n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins Koristeći Git kako biste preuzeli teme].\n: Ovo ne bi trebalo utjecati na vaše git skladište ako ste MediaWiki razvijatelj.\n\n; Ako ste upravo nadogradili MediaWiki:\n: MediaWiki 1.24 i više verzije više ne automatski uključuju uspostavljene teme (pogl. [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Priručni: Samoistraživanje tema]). Možete prekopirati {{PLURAL:$5|sljedeći red kǒda|sljedeće redove kǒda}} u <code>LocalSettings.php</code> kako biste uključili {{PLURAL:$5|uspostavljenu temu|sve uspostavljene teme}}:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Ako ste upravo izmijenili datoteku <code>LocalSettings.php</code>:\n: Provjerite je li ispravno napisani nazivi tema.",
+ "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (uključena)",
+ "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 (<strong>isključena</strong>)",
+ "mediastatistics": "Statistike za slike i snimke",
+ "mediastatistics-summary": "Statistike o poslanih tipovima datoteka. Ovdje su uračunate samo najnovije verzije datoteka. Stare i obrisane verzije nisu uračunate.",
+ "mediastatistics-nbytes": "{{PLURAL:$1|Jedan bajt|$1 bajta|$1 bajtova}} ($2; $3%)",
+ "mediastatistics-bytespertype": "Ukupni obuhvat pasusa: {{PLURAL:$1|$1 bajt|$1 bajta|$1 bajtova}} ($2; $3%).",
+ "mediastatistics-allbytes": "Ukupni obuhvat svih datoteka: {{PLURAL:$1|$1 bajt|$1 bajta|$1 bajtova}} ($2).",
+ "mediastatistics-table-mimetype": "MIME tip",
+ "mediastatistics-table-extensions": "Mogući dodaci",
+ "mediastatistics-table-count": "Broj datoteka",
+ "mediastatistics-table-totalbytes": "Ukupna veličina",
+ "mediastatistics-header-unknown": "Nepoznato",
+ "mediastatistics-header-bitmap": "Bitmap-slika",
+ "mediastatistics-header-drawing": "Crteži (vektorske slike)",
+ "mediastatistics-header-audio": "Zvuk",
+ "mediastatistics-header-video": "Videa",
+ "mediastatistics-header-multimedia": "Obogaćeni snimci",
+ "mediastatistics-header-office": "Birotehničke",
+ "mediastatistics-header-text": "Tekstualne",
+ "mediastatistics-header-executable": "Izvršne",
+ "mediastatistics-header-archive": "Zbijeni formati",
+ "mediastatistics-header-total": "Sve datoteke",
+ "json-warn-trailing-comma": "{{PLURAL:$1|Uklonjena je jedna prateća tačka|Uklonjene su $1 prateća tačka|Uklonjeno je $1 pratećih tački}} iz JSON-a",
+ "json-error-unknown": "Dogodio se problem s JSON-om. Greška: $1",
+ "json-error-depth": "Prekoračena je najveća dozvoljena dubina plasta",
+ "json-error-state-mismatch": "Nevažeći ili pokvareni JSON",
+ "json-error-ctrl-char": "Greška u kontrolnom simbolu. Moguće je da je neispravno enkodiran",
+ "json-error-syntax": "Sintaksna greška",
+ "json-error-utf8": "Pokvareni UTF-8 znaci. Moguće je da su neispravno enkodirani",
+ "json-error-recursion": "Postoji jedna ili više povtorljivih referenci u vrijednosti koju treba enkodirati",
+ "json-error-inf-or-nan": "Postoji jedna ili više NAN- ili INF-vrijednosti što treba enkodirati",
+ "json-error-unsupported-type": "Data je vrijednost tipa što se ne može enkodirati",
+ "headline-anchor-title": "Veza do ovog podnaslova",
+ "special-characters-group-latin": "Latinica",
+ "special-characters-group-latinextended": "Proširena latinica",
+ "special-characters-group-ipa": "IPA",
+ "special-characters-group-symbols": "Simboli",
+ "special-characters-group-greek": "Grčki",
+ "special-characters-group-greekextended": "Prošireni grčki",
+ "special-characters-group-cyrillic": "Ćirilica",
+ "special-characters-group-arabic": "Arapski",
+ "special-characters-group-arabicextended": "Prošireni arapski",
+ "special-characters-group-persian": "Perzijski",
+ "special-characters-group-hebrew": "Hebrejski",
+ "special-characters-group-bangla": "Bengalski",
+ "special-characters-group-tamil": "Tamilski",
+ "special-characters-group-telugu": "Telugu",
+ "special-characters-group-sinhala": "Sinhalski",
+ "special-characters-group-gujarati": "Gudžarati",
+ "special-characters-group-devanagari": "Devanagari",
+ "special-characters-group-thai": "Tajlandski",
+ "special-characters-group-lao": "Laoski",
+ "special-characters-group-khmer": "Kmerski",
+ "special-characters-group-canadianaboriginal": "Kanadski domorodni",
+ "special-characters-title-endash": "crtica",
+ "special-characters-title-emdash": "duga crta",
+ "special-characters-title-minus": "minus",
+ "mw-widgets-abandonedit": "Da li ste sigurni da želite napustiti mod uređivanja bez snimanja izmjena?",
+ "mw-widgets-abandonedit-discard": "Odbaci uređivanja",
"mw-widgets-abandonedit-keep": "Nastavi s uređivanjem",
- "mw-widgets-abandonedit-title": "Da li ste sigurni?"
+ "mw-widgets-abandonedit-title": "Da li ste sigurni?",
+ "mw-widgets-dateinput-no-date": "Datum nije izabran",
+ "mw-widgets-mediasearch-input-placeholder": "Pretražite slike/snimke",
+ "mw-widgets-mediasearch-noresults": "Nisam pronašao ništa.",
+ "mw-widgets-titleinput-description-new-page": "stranica još ne postoji",
+ "mw-widgets-titleinput-description-redirect": "preusmjerava na $1",
+ "mw-widgets-categoryselector-add-category-placeholder": "Dodaj kategoriju...",
+ "mw-widgets-usersmultiselect-placeholder": "Dodaj još...",
+ "mw-widgets-titlesmultiselect-placeholder": "Dodaj još...",
+ "date-range-from": "Od datuma:",
+ "date-range-to": "Do datuma:",
+ "sessionmanager-tie": "Ne možete istovremeno koristiti nekoliko vrsta provjera autentičnosti: $1.",
+ "sessionprovider-generic": "$1 sesije",
+ "sessionprovider-mediawiki-session-cookiesessionprovider": "sesije s kolačićima",
+ "sessionprovider-nocookies": "Kolačići su možda onemogućeni. Ako je tako, uključite ih, i počnite ponovo.",
+ "randomrootpage": "Slučajna korijenska stranica",
+ "log-action-filter-block": "Tip bloka:",
+ "log-action-filter-contentmodel": "Tip promjene sadržajnog modela:",
+ "log-action-filter-delete": "Tip brisanja:",
+ "log-action-filter-import": "Tip uvoza:",
+ "log-action-filter-managetags": "Tip radnje upravljanja oznakama:",
+ "log-action-filter-move": "Tip premještanja:",
+ "log-action-filter-newusers": "Tip stvaranja računa:",
+ "log-action-filter-patrol": "Tip patroliranja:",
+ "log-action-filter-protect": "Tip zaštite:",
+ "log-action-filter-rights": "Tip promjene u pravima:",
+ "log-action-filter-suppress": "Tip skrivanja:",
+ "log-action-filter-upload": "Tip postavljanja:",
+ "log-action-filter-all": "Sve",
+ "log-action-filter-block-block": "blokiranje",
+ "log-action-filter-block-reblock": "Izmjena bloka",
+ "log-action-filter-block-unblock": "Deblokiranje",
+ "log-action-filter-contentmodel-change": "Promjena sadržajnog modela",
+ "log-action-filter-contentmodel-new": "Pravljenje stranice s nestandardnim sadržajnim modelom",
+ "log-action-filter-delete-delete": "Brisanje stranice",
+ "log-action-filter-delete-delete_redir": "Presnimavanje preusmjerenja",
+ "log-action-filter-delete-restore": "Povratak stranice",
+ "log-action-filter-delete-event": "Brisanje evidencije",
+ "log-action-filter-delete-revision": "Brisanje izmjene",
+ "log-action-filter-import-interwiki": "Prekowiki-uvoz",
+ "log-action-filter-import-upload": "Uvoz postavljanjem XML-a",
+ "log-action-filter-managetags-create": "Stvaranje oznake",
+ "log-action-filter-managetags-delete": "Brisanje oznake",
+ "log-action-filter-managetags-activate": "Aktiviranje oznake",
+ "log-action-filter-managetags-deactivate": "Deaktiviranje oznake",
+ "log-action-filter-move-move": "Premještanje bez presnimavanja preusmjerenja",
+ "log-action-filter-move-move_redir": "Premještanje s presnimavanjem preusmjerenja",
+ "log-action-filter-newusers-create": "Stvorio anonimni korisnik",
+ "log-action-filter-newusers-create2": "Stvorio registrirani korisnik",
+ "log-action-filter-newusers-autocreate": "Automatski stvoren",
+ "log-action-filter-newusers-byemail": "Stvoren lozinkom poslanom na adresu e-pošte",
+ "log-action-filter-patrol-patrol": "Ručno patrolirano",
+ "log-action-filter-patrol-autopatrol": "Automatski patrolirano",
+ "log-action-filter-protect-protect": "Zaštita",
+ "log-action-filter-protect-modify": "Izmjena zaštite",
+ "log-action-filter-protect-unprotect": "Odzaštita",
+ "log-action-filter-protect-move_prot": "Premještanje zaštite",
+ "log-action-filter-rights-rights": "Ručna promjena",
+ "log-action-filter-rights-autopromote": "Automatska promjena",
+ "log-action-filter-suppress-event": "Skrivanje zapisa u evidenciji",
+ "log-action-filter-suppress-revision": "Skrivanje izmjene",
+ "log-action-filter-suppress-delete": "Skrivanje stranice",
+ "log-action-filter-suppress-block": "Skrivanje korisnikota preko blokiranja",
+ "log-action-filter-suppress-reblock": "Skrivanje korisnikota preko preblokiranja",
+ "log-action-filter-upload-upload": "Novo postavljanje",
+ "log-action-filter-upload-overwrite": "Prepostavljanje",
+ "log-action-filter-upload-revert": "Vrati",
+ "authmanager-authn-not-in-progress": "Verifikacija nije u toku, ili ima gubitak podataka o sesiji. Počnite ispočetka.",
+ "authmanager-authn-no-primary": "Pruženi akreditivi ne mogu se verificirati.",
+ "authmanager-authn-no-local-user": "Pruženi akreditivi nisu povezani ni s jednim korisnikom na ovom wikiju.",
+ "authmanager-authn-no-local-user-link": "Pruženi akreditivi su važeći, ali nisu povezani ni s jednim korisnikom na ovom wikiju. Prijavite se na drugačiji način, ili napravite novi korisnički račun, što će vam dati mogućnost da svežete prethodne akreditive na novi račun.",
+ "authmanager-authn-autocreate-failed": "Automatsko stvaranje mjesnog računa nije uspjelo: $1",
+ "authmanager-change-not-supported": "Pružene akreditive ne mogu se mijenjati, jer ih ništa ne bi koristilo.",
+ "authmanager-create-disabled": "Onemogućeno pravljenje računa.",
+ "authmanager-create-from-login": "Popunite polja da biste napravili račun.",
+ "authmanager-create-not-in-progress": "Pravljenje računa nije u toku, ili ima gubitak podataka o sesiji. Počnite ispočetka.",
+ "authmanager-create-no-primary": "Pružene akreditive ne mogu se uporabiti za otvaranje naloga.",
+ "authmanager-link-no-primary": "Pružene akreditive ne mogu se uporabiti u povezivanju naloga.",
+ "authmanager-link-not-in-progress": "Spajanje naloga nije u toku, ili ima gubitak podataka o sesiji. Počnite ispočetka.",
+ "authmanager-autocreate-noperm": "Automatsko pravljenje računa nije dozvoljeno.",
+ "authmanager-autocreate-exception": "Automatsko pravljenje računa privremeno je onemogućeno zbog prijašnjih greški.",
+ "authmanager-userdoesnotexist": "Korisnički račun \"$1\" nije registrovan.",
+ "userjsispublic": "Napomena: podstranice s JavaScriptom ne bi trebale sadržavati povjerljive podatke budući da ih drugi korisnici mogu vidjeti.",
+ "userjsonispublic": "Imajte na umu: Podstranice s JSONom ne bi trebale sadržavati povjerljive podatke budući da su vidljive drugim korisnicima.",
+ "usercssispublic": "Napomena: podstranice s CSS-om ne bi trebale sadržavati povjerljive podatke budući da ih drugi korisnici mogu vidjeti.",
+ "restrictionsfield-badip": "Nevažeća IP adresa ili opseg: $1",
+ "restrictionsfield-label": "Dozvoljeni IP-opsezi:",
+ "restrictionsfield-help": "Jedna IP-adresa ili CIDR-opseg po redu. Da omogućite sve, koristite<br /><code>0.0.0.0/0</code><br /><code>::/0</code>",
+ "edit-error-short": "Greška: $1",
+ "edit-error-long": "Greške:\n\n$1",
+ "revid": "izmjena $1",
+ "pageid": "ID stranice $1"
}
"ipb-blocklist-contribs": "{{GENDER:$1|$1}} için katkılar",
"ipb-blocklist-duration-left": "$1 ayrıldı",
"block-expiry": "Bitiş süresi",
+ "block-target": "Kullanıcı adı veya IP adresi:",
"unblockip": "Kullanıcının engellemesini kaldır",
"unblockiptext": "Daha önceden engellenmiş bir IP adresine ya da kullanıcı adına yazma erişimini geri vermek için aşağıdaki formu kullanın.",
"ipusubmit": "Bu engellemeyi kaldır",
"emailblock": "e-posta engellendi",
"blocklist-nousertalk": "kendi mesaj sayfasını değiştiremez",
"blocklist-editing-sitewide": "düzenleme (site geneli)",
+ "blocklist-editing-page": "sayfalar",
+ "blocklist-editing-ns": "ad alanı",
"ipblocklist-empty": "Engelleme listesi boş.",
"ipblocklist-no-results": "İstenen IP adresi ya da kullanıcı adı engellenmedi.",
"blocklink": "engelle",
* @author Rob Church <robchur@gmail.com>
*/
public function purgeRedundantText( $delete = true ) {
+ global $wgMultiContentRevisionSchemaMigrationStage;
+
# Data should come off the master, wrapped in a transaction
$dbw = $this->getDB( DB_MASTER );
$this->beginTransaction( $dbw, __METHOD__ );
- # Get "active" text records from the revisions table
- $cur = [];
- $this->output( 'Searching for active text records in revisions table...' );
- $res = $dbw->select( 'revision', 'rev_text_id', [], __METHOD__, [ 'DISTINCT' ] );
- foreach ( $res as $row ) {
- $cur[] = $row->rev_text_id;
- }
- $this->output( "done.\n" );
+ if ( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_READ_OLD ) {
+ # Get "active" text records from the revisions table
+ $cur = [];
+ $this->output( 'Searching for active text records in revisions table...' );
+ $res = $dbw->select( 'revision', 'rev_text_id', [], __METHOD__, [ 'DISTINCT' ] );
+ foreach ( $res as $row ) {
+ $cur[] = $row->rev_text_id;
+ }
+ $this->output( "done.\n" );
- # Get "active" text records from the archive table
- $this->output( 'Searching for active text records in archive table...' );
- $res = $dbw->select( 'archive', 'ar_text_id', [], __METHOD__, [ 'DISTINCT' ] );
- foreach ( $res as $row ) {
- # old pre-MW 1.5 records can have null ar_text_id's.
- if ( $row->ar_text_id !== null ) {
- $cur[] = $row->ar_text_id;
+ # Get "active" text records from the archive table
+ $this->output( 'Searching for active text records in archive table...' );
+ $res = $dbw->select( 'archive', 'ar_text_id', [], __METHOD__, [ 'DISTINCT' ] );
+ foreach ( $res as $row ) {
+ # old pre-MW 1.5 records can have null ar_text_id's.
+ if ( $row->ar_text_id !== null ) {
+ $cur[] = $row->ar_text_id;
+ }
+ }
+ $this->output( "done.\n" );
+ } else {
+ # Get "active" text records via the content table
+ $cur = [];
+ $this->output( 'Searching for active text records via contents table...' );
+ $res = $dbw->select( 'content', 'content_address', [], __METHOD__, [ 'DISTINCT' ] );
+ $blobStore = MediaWikiServices::getInstance()->getBlobStore();
+ foreach ( $res as $row ) {
+ $textId = $blobStore->getTextIdFromAddress( $row->content_address );
+ if ( $textId ) {
+ $cur[] = $textId;
+ }
}
+ $this->output( "done.\n" );
}
$this->output( "done.\n" );
require_once __DIR__ . '/../includes/export/WikiExporter.php';
use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\BlobAccessException;
+use MediaWiki\Storage\BlobStore;
+use MediaWiki\Storage\SqlBlobStore;
use Wikimedia\Rdbms\IMaintainableDatabase;
/**
}
}
+ /**
+ * @return BlobStore
+ */
+ private function getBlobStore() {
+ return MediaWikiServices::getInstance()->getBlobStore();
+ }
+
function execute() {
$this->processOptions();
$this->dump( true );
}
/**
- * Tries to get the revision text for a revision id.
- * Export transformations are applied if the content model can is given or can be
+ * Tries to load revision text.
+ * Export transformations are applied if the content model is given or can be
* determined from the database.
*
* Upon errors, retries (Up to $this->maxFailures tries each call).
- * If still no good revision get could be found even after this retrying, "" is returned.
+ * If still no good revision could be found even after this retrying, "" is returned.
* If no good revision text could be returned for
* $this->maxConsecutiveFailedTextRetrievals consecutive calls to getText, MWException
* is thrown.
*
- * @param string $id The revision id to get the text for
+ * @param int|string $id Content address, or text row ID.
* @param string|bool|null $model The content model used to determine
* applicable export transformations.
* If $model is null, it will be determined from the database.
$consecutiveFailedTextRetrievals = 0;
if ( $model === null && $wgContentHandlerUseDB ) {
+ // TODO: MCR: use content table
$row = $this->db->selectRow(
'revision',
[ 'rev_content_model', 'rev_content_format' ],
}
/**
- * May throw a database error if, say, the server dies during query.
- * @param int $id
+ * Loads the serialized content from storage.
+ *
+ * @param int|string $id Content address, or text row ID.
* @return bool|string
- * @throws MWException
*/
private function getTextDb( $id ) {
- if ( !isset( $this->db ) ) {
- throw new MWException( __METHOD__ . "No database available" );
- }
- $row = $this->db->selectRow( 'text',
- [ 'old_text', 'old_flags' ],
- [ 'old_id' => $id ],
- __METHOD__ );
- $text = Revision::getRevisionText( $row );
- if ( $text === false ) {
+ $store = $this->getBlobStore();
+ $address = ( is_int( $id ) || strpos( $id, ':' ) === false )
+ ? SqlBlobStore::makeAddressFromTextId( (int)$id )
+ : $id;
+
+ try {
+ $text = $store->getBlob( $address );
+
+ $stripped = str_replace( "\r", "", $text );
+ $normalized = MediaWikiServices::getInstance()->getContentLanguage()
+ ->normalize( $stripped );
+
+ return $normalized;
+ } catch ( BlobAccessException $ex ) {
+ // XXX: log a warning?
return false;
}
- $stripped = str_replace( "\r", "", $text );
- $normalized = MediaWikiServices::getInstance()->getContentLanguage()->
- normalize( $stripped );
-
- return $normalized;
}
+ /**
+ * @param int|string $id Content address, or text row ID.
+ * @return bool|string
+ */
private function getTextSpawned( $id ) {
Wikimedia\suppressWarnings();
if ( !$this->spawnProc ) {
Wikimedia\restoreWarnings();
}
+ /**
+ * @param int|string $id Content address, or text row ID.
+ * @return bool|string
+ */
private function getTextSpawnedOnce( $id ) {
$ok = fwrite( $this->spawnWrite, "$id\n" );
// $this->progress( ">> $id" );
// check that the text id they are sending is the one we asked for
// this avoids out of sync revision text errors we have encountered in the past
- $newId = fgets( $this->spawnRead );
- if ( $newId === false ) {
+ $newAddress = fgets( $this->spawnRead );
+ if ( $newAddress === false ) {
return false;
}
+ if ( strpos( $newAddress, ':' ) === false ) {
+ $newId = intval( $newAddress );
+ if ( $newId === false ) {
+ return false;
+ }
+ } else {
+ try {
+ $newAddressFields = SqlBlobStore::splitBlobAddress( $newAddress );
+ $newId = $newAddressFields[ 1 ];
+ } catch ( InvalidArgumentException $ex ) {
+ return false;
+ }
+ }
if ( $id != intval( $newId ) ) {
return false;
}
require_once __DIR__ . '/Maintenance.php';
-use Wikimedia\Rdbms\IDatabase;
+use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\BlobAccessException;
+use MediaWiki\Storage\SqlBlobStore;
/**
* Maintenance script used to fetch page text in a subprocess.
* @ingroup Maintenance
*/
class FetchText extends Maintenance {
+
public function __construct() {
parent::__construct();
- $this->addDescription( "Fetch the raw revision blob from an old_id.\n" .
+
+ $this->addDescription( "Fetch the raw revision blob from a blob address.\n" .
+ "Integer IDs are interpreted as referring to text.old_id for backwards compatibility.\n" .
"NOTE: Export transformations are NOT applied. " .
- "This is left to backupTextPass.php"
+ "This is left to dumpTextPass.php"
);
}
+ /**
+ * @return SqlBlobStore
+ */
+ private function getBlobStore() {
+ return MediaWikiServices::getInstance()->getBlobStore();
+ }
+
/**
* returns a string containing the following in order:
* textid
* note that the text string itself is *not* followed by newline
*/
public function execute() {
- $db = $this->getDB( DB_REPLICA );
$stdin = $this->getStdin();
while ( !feof( $stdin ) ) {
$line = fgets( $stdin );
// We appear to have lost contact...
break;
}
- $textId = intval( $line );
- $text = $this->doGetText( $db, $textId );
- if ( $text === false ) {
- # actual error, not zero-length text
- $textLen = "-1";
- } else {
+ $blobAddress = trim( $line );
+
+ // Plain integers are supported for backwards compatibility with pre-MCR dumps.
+ if ( strpos( $blobAddress, ':' ) === false && is_numeric( $blobAddress ) ) {
+ $blobAddress = SqlBlobStore::makeAddressFromTextId( intval( $blobAddress ) );
+ }
+
+ try {
+ $text = $this->getBlobStore()->getBlob( $blobAddress );
$textLen = strlen( $text );
+ } catch ( BlobAccessException $ex ) {
+ // XXX: log $ex to stderr?
+ $textLen = '-1';
+ $text = '';
+ } catch ( InvalidArgumentException $ex ) {
+ // XXX: log $ex to stderr?
+ $textLen = '-1';
+ $text = '';
}
- $this->output( $textId . "\n" . $textLen . "\n" . $text );
- }
- }
- /**
- * May throw a database error if, say, the server dies during query.
- * @param IDatabase $db
- * @param int $id The old_id
- * @return string
- */
- private function doGetText( $db, $id ) {
- $id = intval( $id );
- $row = $db->selectRow( 'text',
- [ 'old_text', 'old_flags' ],
- [ 'old_id' => $id ],
- __METHOD__ );
- $text = Revision::getRevisionText( $row );
- if ( $text === false ) {
- return false;
+ $this->output( $blobAddress . "\n" . $textLen . "\n" . $text );
}
-
- return $text;
}
+
}
$maintClass = FetchText::class;
$throttle = intval( $throttle );
if ( $begin !== '' ) {
- $where = 'cl_to > ' . $dbw->addQuotes( $begin );
+ $where = [ 'cl_to > ' . $dbw->addQuotes( $begin ) ];
} else {
- $where = null;
+ $where = [ '1 = 1' ];
}
$i = 0;
$startOption = 'start-archive';
}
+ if ( !$this->dbw->fieldExists( $table, $fields['text_id'], __METHOD__ ) ) {
+ $this->writeln( "No need to populate, $table.{$fields['text_id']} field does not exist" );
+ return;
+ }
+
$minmax = $this->dbw->selectRow(
$table,
[ 'min' => "MIN( $idField )", 'max' => "MAX( $idField )" ],
$this->output( "Rebuilding index fields for {$count} pages...\n" );
$n = 0;
- $revQuery = Revision::getQueryInfo( [ 'page', 'text' ] );
+ $revQuery = Revision::getQueryInfo( [ 'page' ] );
while ( $n < $count ) {
if ( $n ) {
$res = $this->db->select(
$revQuery['tables'],
$revQuery['fields'],
- [ "page_id BETWEEN $n AND $end", 'page_latest = rev_id', 'rev_text_id = old_id' ],
+ [ "page_id BETWEEN $n AND $end", 'page_latest = rev_id' ],
__METHOD__,
[],
$revQuery['joins']
$table = $( table ),
firstTime = true;
+ // Don't construct twice on the same table
+ if ( $.data( table, 'tablesorter' ) ) {
+ return;
+ }
// Quit if no tbody
if ( !table.tBodies ) {
return;
@import 'mediawiki.mixins';
-.TablePager {
+// TablePager uses `.mw-datatable` and is loaded in the right order by RL
+.mw-datatable {
min-width: 80%;
- // Remove as soon as `.mw-datatable` receives this `padding`, see T214208
- td,
- th {
- padding: 0.2em 0.4em;
- }
-}
-
-.mw-datatable {
&-is-sorted a {
background-position: left center;
background-repeat: no-repeat;
File containing double quotes and spaces
!! wikitext
[[File:Cool "Gator".png]]
+!! html/php+tidy
+<p><a href="/index.php?title=Special:Upload&wpDestFile=Cool_%22Gator%22.png" class="new" title="File:Cool "Gator".png">File:Cool "Gator".png</a>
+</p>
!! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-parsoid='{"optList":[]}' data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./File:Cool_%22Gator%22.png" data-parsoid='{"a":{"href":"./File:Cool_%22Gator%22.png"},"sa":{"href":"File:Cool \"Gator\".png"}}'><img resource='./File:Cool_"Gator".png' src="./Special:FilePath/Cool_%22Gator%22.png" height="220" width="220" data-parsoid='{"a":{"resource":"./File:Cool_\"Gator\".png","height":"220","width":"220","src":"./Special:FilePath/Cool_%22Gator%22.png"},"sa":{"resource":"File:Cool \"Gator\".png","src":"./Special:FilePath/Cool_\"Gator\".png"}}'/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Cool_%22Gator%22.png"><span resource='./File:Cool_"Gator".png' data-parsoid='{"a":{"resource":"./File:Cool_\"Gator\".png"},"sa":{"resource":"File:Cool \"Gator\".png"}}'>File:Cool "Gator".png</span></a></figure-inline></p>
!! end
!! test
</p>
!! end
+## FIXME: Title part of filename is interpreted in php
!! test
Link with double quotes in title part (literal) and alternate part (interpreted)
!! wikitext
</p><p><a href="/index.php?title=%27%27Pentecoste%27%27&action=edit&redlink=1" class="new" title="''Pentecoste'' (page does not exist)"><i>Pentecoste</i></a>
</p>
!! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./File:Denys_Savchenko_''Pentecoste''.jpg"><img resource="./File:Denys_Savchenko_''Pentecoste''.jpg" src="./Special:FilePath/Denys_Savchenko_''Pentecoste''.jpg" height="220" width="220"/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Denys_Savchenko_''Pentecoste''.jpg"><span resource="./File:Denys_Savchenko_''Pentecoste''.jpg" data-parsoid='{"a":{"resource":"./File:Denys_Savchenko_''Pentecoste''.jpg"},"sa":{"resource":"File:Denys_Savchenko_''Pentecoste''.jpg"}}'>File:Denys Savchenko ''Pentecoste''.jpg</span></a></figure-inline></p>
<p><a rel="mw:WikiLink" href="./''Pentecoste''" title="''Pentecoste''">''Pentecoste''</a></p>
<p><a rel="mw:WikiLink" href="./''Pentecoste''" title="''Pentecoste''">Pentecoste</a></p>
<p><a rel="mw:WikiLink" href="./''Pentecoste''" title="''Pentecoste''"><i>Pentecoste</i></a></p>
<a href="/index.php?title=Special:Upload&wpDestFile=Nonexistent" class="new" title="File:Nonexistent">abc</a>
</p>
!! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"<script></script>"}]}' data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}],"caption":"&lt;script>&lt;/script>"}'><a href="./File:Nonexistent" data-parsoid='{"a":{"href":"./File:Nonexistent"},"sa":{}}'><img resource="./File:Nonexistent" src="./Special:FilePath/Nonexistent" height="220" width="220" data-parsoid='{"a":{"resource":"./File:Nonexistent","height":"220","width":"220"},"sa":{"resource":"File:Nonexistent"}}'/></a></figure-inline>
-<figure-inline typeof="mw:Error mw:Image" data-parsoid='{"optList":[{"ck":"width","ak":"100x100px"},{"ck":"caption","ak":"<script></script>"}]}' data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}],"caption":"&lt;script>&lt;/script>"}'><a href="./File:Nonexistent" data-parsoid='{"a":{"href":"./File:Nonexistent"},"sa":{}}'><img resource="./File:Nonexistent" src="./Special:FilePath/Nonexistent" height="100" width="100" data-parsoid='{"a":{"resource":"./File:Nonexistent","height":"100","width":"100"},"sa":{"resource":"File:Nonexistent"}}'/></a></figure-inline>
-<figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"&lt;"}]}' data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}],"caption":"<span typeof=\"mw:Entity\" data-parsoid='{\"src\":\"&amp;lt;\",\"srcContent\":\"&lt;\",\"dsr\":[107,111,null,null]}'>&lt;</span>"}'><a href="./File:Nonexistent" data-parsoid='{"a":{"href":"./File:Nonexistent"},"sa":{}}'><img resource="./File:Nonexistent" src="./Special:FilePath/Nonexistent" height="220" width="220" data-parsoid='{"a":{"resource":"./File:Nonexistent","height":"220","width":"220"},"sa":{"resource":"File:Nonexistent"}}'/></a></figure-inline>
-<figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"a<i>b</i>c"}]}' data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}],"caption":"a<i data-parsoid='{\"stx\":\"html\",\"dsr\":[134,142,3,4]}'>b</i>c"}'><a href="./File:Nonexistent" data-parsoid='{"a":{"href":"./File:Nonexistent"},"sa":{}}'><img resource="./File:Nonexistent" src="./Special:FilePath/Nonexistent" height="220" width="220" data-parsoid='{"a":{"resource":"./File:Nonexistent","height":"220","width":"220"},"sa":{"resource":"File:Nonexistent"}}'/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"<script></script>"}]}' data-mw='{"caption":"&lt;script>&lt;/script>","errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Nonexistent"><span resource="./File:Nonexistent" data-parsoid='{"a":{"resource":"./File:Nonexistent"},"sa":{"resource":"File:Nonexistent"}}'>File:Nonexistent</span></a></figure-inline>
+<figure-inline typeof="mw:Error mw:Image" data-parsoid='{"optList":[{"ck":"width","ak":"100x100px"},{"ck":"caption","ak":"<script></script>"}]}' data-mw='{"caption":"&lt;script>&lt;/script>","errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Nonexistent"><span resource="./File:Nonexistent" data-width="100" data-height="100" data-parsoid='{"a":{"resource":"./File:Nonexistent"},"sa":{"resource":"File:Nonexistent"}}'>File:Nonexistent</span></a></figure-inline>
+<figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"&lt;"}]}' data-mw='{"caption":"<span typeof=\"mw:Entity\" data-parsoid='{\"src\":\"&amp;lt;\",\"srcContent\":\"&lt;\",\"dsr\":[107,111,null,null]}'>&lt;</span>","errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Nonexistent"><span resource="./File:Nonexistent" data-parsoid='{"a":{"resource":"./File:Nonexistent"},"sa":{"resource":"File:Nonexistent"}}'>File:Nonexistent</span></a></figure-inline>
+<figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"a<i>b</i>c"}]}' data-mw='{"caption":"a<i data-parsoid='{\"stx\":\"html\",\"dsr\":[134,142,3,4]}'>b</i>c","errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Nonexistent"><span resource="./File:Nonexistent" data-parsoid='{"a":{"resource":"./File:Nonexistent"},"sa":{"resource":"File:Nonexistent"}}'>File:Nonexistent</span></a></figure-inline></p>
!! end
!! test
</p>
!! end
+!! test
+Plain link to URL containing special characters, with link text (see T213950).
+!! wikitext
+[[http://www.example.com/?q=%7Babc%7D Link text]]
+!! html
+<p>[<a rel="nofollow" class="external text" href="http://www.example.com/?q=%7Babc%7D">Link text</a>]
+</p>
+!! end
+
!! test
Plain link to protocol-relative URL
!! wikitext
!! html+tidy
<p>This is a test template with parameter </p><div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/index.php?title=Special:Upload&wpDestFile=Noimage.png" class="new" title="File:Noimage.png">File:Noimage.png</a> <div class="thumbcaption"><a href="/index.php?title=No_link&action=edit&redlink=1" class="new" title="No link (page does not exist)">link</a> <a href="/index.php?title=No_link&action=edit&redlink=1" class="new" title="No link (page does not exist)">caption</a></div></div></div>
!! html/parsoid
-<p about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"paramtest","href":"./Template:Paramtest"},"params":{"param":{"wt":"[[Image:noimage.png|thumb|[[no link|link]] [[no link|caption]]]]"}},"i":0}}]}'>This is a test template with parameter </p><figure class="mw-default-size" typeof="mw:Error mw:Image/Thumb" about="#mwt1" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./File:Noimage.png" ><img resource="./File:Noimage.png" src="./Special:FilePath/Noimage.png" height="220" width="220"/></a><figcaption><a rel="mw:WikiLink" href="./No_link" title="No link">link</a> <a rel="mw:WikiLink" href="./No_link" title="No link">caption</a></figcaption></figure>
+<p about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"paramtest","href":"./Template:Paramtest"},"params":{"param":{"wt":"[[Image:noimage.png|thumb|[[no link|link]] [[no link|caption]]]]"}},"i":0}}]}'>This is a test template with parameter </p><figure class="mw-default-size" typeof="mw:Error mw:Image/Thumb" about="#mwt1" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Noimage.png"><span resource="./File:Noimage.png" data-width="220">File:Noimage.png</span></a><figcaption><a rel="mw:WikiLink" href="./No_link" title="No link">link</a> <a rel="mw:WikiLink" href="./No_link" title="No link">caption</a></figcaption></figure>
!! end
!! article
</p>
!! end
+# FIXME: Parsoid's markup for this is quite ugly.
!! test
<includeonly> and <noinclude> on a page
!! wikitext
Foo<noinclude>zar</noinclude><includeonly>bar</includeonly>
-!! html
+!! html/php+tidy
<p>Foozar
</p>
+!! html/parsoid
+<p>Foo<meta typeof="mw:Includes/NoInclude" data-parsoid="{}"/>zar</p><meta typeof="mw:Includes/NoInclude/End" data-parsoid="{}"/><meta typeof="mw:Includes/IncludeOnly" data-mw='{"src":"<includeonly>bar</includeonly>"}' data-parsoid="{}"/><meta typeof="mw:Includes/IncludeOnly/End" data-parsoid="{}"/>
!! end
!! test
</p>
!!end
+!! test
+File with template filename
+!! wikitext
+[[File:{{echo|Foobar.jpg}}]]
+!! html/parsoid
+<p><figure-inline class="mw-default-size" typeof="mw:Image mw:ExpandedAttrs" data-mw='{"attribs":[[{"txt":"href"},{"html":"File:<span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid='{\"pi\":[[{\"k\":\"1\"}]],\"dsr\":[7,26,null,null]}' data-mw='{\"parts\":[{\"template\":{\"target\":{\"wt\":\"echo\",\"href\":\"./Template:Echo\"},\"params\":{\"1\":{\"wt\":\"Foobar.jpg\"}},\"i\":0}}]}'>Foobar.jpg</span>"}]]}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"File:{{echo|Foobar.jpg}}"}}'/></a></figure-inline></p>
+!! end
+
!!test
Templates: HTML Tag: 1. Generation of HTML attr. key
!! wikitext
!! html/php
<div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" /></a></div>
!! html/parsoid
-<figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure>
+<figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption></figcaption></figure>
!! end
!! test
!! html/php
<div class="thumb tright"><div class="thumbinner" style="width:139px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/137px-Foobar.jpg" decoding="async" width="137" height="16" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/206px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/274px-Foobar.jpg 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>This is a caption</div></div></div>
!! html/parsoid
-<figure typeof="mw:Image/Thumb mw:ExpandedAttrs" about="#mwt2" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"width","ak":"{{echo|137px}}"},{"ck":"caption","ak":"This is a caption"}]}' data-mw='{"attribs":[["thumbnail",{"html":"thumb"}],["width",{"html":"<span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid='{\"pi\":[[{\"k\":\"1\"}]],\"dsr\":[24,38,null,null]}' data-mw='{\"parts\":[{\"template\":{\"target\":{\"wt\":\"echo\",\"href\":\"./Template:Echo\"},\"params\":{\"1\":{\"wt\":\"137px\"}},\"i\":0}}]}'>137px</span>"}]]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/137px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="16" width="137" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"16","width":"137"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption>This is a caption</figcaption></figure>
+<figure typeof="mw:Image/Thumb mw:ExpandedAttrs" about="#mwt2" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"width","ak":"{{echo|137px}}"},{"ck":"caption","ak":"This is a caption"}]}' data-mw='{"attribs":[["width",{"html":"<span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid='{\"pi\":[[{\"k\":\"1\"}]],\"dsr\":[24,38,null,null]}' data-mw='{\"parts\":[{\"template\":{\"target\":{\"wt\":\"echo\",\"href\":\"./Template:Echo\"},\"params\":{\"1\":{\"wt\":\"137px\"}},\"i\":0}}]}'>137px</span>"}]]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/137px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="16" width="137" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"16","width":"137"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption>This is a caption</figcaption></figure>
!! end
!! test
123</p><div class="thumb tright"><div class="thumbinner" style="width:222px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" decoding="async" width="220" height="25" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/330px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/440px-Foobar.jpg 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div></div></div></div><p>456</p>
!! html/parsoid
<p>123<figure-inline class="mw-default-size" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline>456</p>
-<p>123</p><figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure><p>456
-123</p><figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a></figure><p>456</p>
+<p>123</p><figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption></figcaption></figure><p>456
+123</p><figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption></figcaption></figure><p>456</p>
!! end
!! test
!! html/php
<div class="thumb tright"><div class="thumbinner" style="width:137px;"><a href="/wiki/File:Foobar.jpg"><img alt="" src="http://example.com/images/e/ea/Thumb.png" decoding="async" width="135" height="135" class="thumbimage" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>Title</div></div></div>
!! html/parsoid
+<figure class="mw-default-size" typeof="mw:Image/Thumb" about="#mwt1" data-mw='{"attribs":[["manualthumb",{"txt":"Thumb.png"}]]}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></a><figcaption>Title</figcaption></figure>
+!! end
+
+!! test
+Manually-specified thumbnail image (backwards compat)
+!! options
+thumbsize=220
+parsoid=html2wt
+!! wikitext
+[[File:Foobar.jpg|thumbnail=Thumb.png|Title]]
+!! html/php
+<div class="thumb tright"><div class="thumbinner" style="width:137px;"><a href="/wiki/File:Foobar.jpg"><img alt="" src="http://example.com/images/e/ea/Thumb.png" decoding="async" width="135" height="135" class="thumbimage" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>Title</div></div></div>
+!! html/parsoid
<figure class="mw-default-size" typeof="mw:Image/Thumb" data-mw='{"thumb":"Thumb.png"}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></a><figcaption>Title</figcaption></figure>
!! end
!! html/php
<div class="thumb tright"><div class="thumbinner" style="width:137px;"><a href="/wiki/Main_Page" title="Main Page"><img alt="" src="http://example.com/images/e/ea/Thumb.png" decoding="async" width="135" height="135" class="thumbimage" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>Title</div></div></div>
!! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb" data-mw='{"thumb":"Thumb.png"}'><a href="./Main_Page"><img resource="./File:Foobar.jpg" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></a><figcaption>Title</figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb" data-mw='{"attribs":[["manualthumb",{"txt":"Thumb.png"}]]}'><a href="./Main_Page"><img resource="./File:Foobar.jpg" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></a><figcaption>Title</figcaption></figure>
!! end
!! test
!! html/php
<div class="thumb tright"><div class="thumbinner" style="width:137px;"><a href="http://example.com"><img alt="" src="http://example.com/images/e/ea/Thumb.png" decoding="async" width="135" height="135" class="thumbimage" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>Title</div></div></div>
!! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb" data-mw='{"thumb":"Thumb.png"}'><a href="http://example.com"><img resource="./File:Foobar.jpg" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></a><figcaption>Title</figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb" data-mw='{"attribs":[["manualthumb",{"txt":"Thumb.png"}]]}'><a href="http://example.com"><img resource="./File:Foobar.jpg" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></a><figcaption>Title</figcaption></figure>
!! end
!! test
!! html/php
<div class="thumb tright"><div class="thumbinner" style="width:137px;"><img alt="" src="http://example.com/images/e/ea/Thumb.png" decoding="async" width="135" height="135" class="thumbimage" /> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>Title</div></div></div>
!! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb" data-mw='{"thumb":"Thumb.png"}'><span><img resource="./File:Foobar.jpg" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></span><figcaption>Title</figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb" data-mw='{"attribs":[["manualthumb",{"txt":"Thumb.png"}]]}'><span><img resource="./File:Foobar.jpg" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></span><figcaption>Title</figcaption></figure>
!! end
!! test
!! html/php
<div class="thumb tright"><div class="thumbinner" style="width:137px;"><a href="/wiki/Main_Page" title="Main Page"><img alt="alttext" src="http://example.com/images/e/ea/Thumb.png" decoding="async" width="135" height="135" class="thumbimage" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>Title</div></div></div>
!! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb" data-mw='{"thumb":"Thumb.png"}'><a href="./Main_Page"><img alt="alttext" resource="./File:Foobar.jpg" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></a><figcaption>Title</figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb" data-mw='{"attribs":[["manualthumb",{"txt":"Thumb.png"}]]}'><a href="./Main_Page"><img alt="alttext" resource="./File:Foobar.jpg" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></a><figcaption>Title</figcaption></figure>
!! end
!! test
!! html/parsoid
<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"testing '''bold''' in alt"}]}' data-mw='{"caption":"testing <b data-parsoid='{\"dsr\":[27,37,3,3]}'>bold</b> in alt"}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{}}'><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"Image:Foobar.jpg"}}'/></a></figure-inline></p>
-<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"alt","ak":"alt=testing '''bold''' in alt"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{}}'><img alt="testing bold in alt" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"alt":"testing bold in alt","resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"alt":"alt=testing '''bold''' in alt","resource":"Image:Foobar.jpg"}}'/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Image mw:ExpandedAttrs" about="#mwt1" data-parsoid='{"optList":[{"ck":"alt","ak":"alt=testing '''bold''' in alt"}]}' data-mw='{"attribs":[["alt",{"html":"alt=testing <b data-parsoid='{\"dsr\":[79,89,3,3]}'>bold</b> in alt","txt":"testing bold in alt"}]]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{"href":"Image:Foobar.jpg"}}'><img alt="testing bold in alt" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"Image:Foobar.jpg"}}'/></a></figure-inline></p>
!! end
!! test
!! html/php
<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="This is a link and a bold template." src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" decoding="async" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>This is the image caption</div></div></div>
!! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb mw:ExpandedAttrs" about="#mwt2" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"caption","ak":"This is the image caption"},{"ck":"alt","ak":"alt=This is a [[link]] and a {{echo|''bold template''}}."}]}' data-mw='{"attribs":[["thumbnail",{"html":"thumb"}],["alt",{"html":"alt=This is a <a rel=\"mw:WikiLink\" href=\"./Link\" title=\"Link\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Link\"},\"sa\":{\"href\":\"link\"},\"dsr\":[65,73,2,2]}'>link</a> and a <i about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid='{\"dsr\":[80,106,null,null],\"pi\":[[{\"k\":\"1\"}]]}' data-mw='{\"parts\":[{\"template\":{\"target\":{\"wt\":\"echo\",\"href\":\"./Template:Echo\"},\"params\":{\"1\":{\"wt\":\"&apos;&apos;bold template&apos;&apos;\"}},\"i\":0}}]}'>bold template</i>."}]]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{}}'><img alt="This is a link and a bold template." resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220" data-parsoid='{"a":{"alt":"This is a link and a bold template.","resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"alt":"alt=This is a [[link]] and a {{echo|''bold template''}}.","resource":"Image:Foobar.jpg"}}'/></a><figcaption>This is the image caption</figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb mw:ExpandedAttrs" about="#mwt2" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"caption","ak":"This is the image caption"},{"ck":"alt","ak":"alt=This is a [[link]] and a {{echo|''bold template''}}."}]}' data-mw='{"attribs":[["alt",{"html":"alt=This is a <a rel=\"mw:WikiLink\" href=\"./Link\" title=\"Link\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Link\"},\"sa\":{\"href\":\"link\"},\"dsr\":[65,73,2,2]}'>link</a> and a <i about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid='{\"dsr\":[80,106,null,null],\"pi\":[[{\"k\":\"1\"}]]}' data-mw='{\"parts\":[{\"template\":{\"target\":{\"wt\":\"echo\",\"href\":\"./Template:Echo\"},\"params\":{\"1\":{\"wt\":\"&apos;&apos;bold template&apos;&apos;\"}},\"i\":0}}]}'>bold template</i>.","txt":"This is a link and a bold template."}]]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{"href":"Image:Foobar.jpg"}}'><img alt="This is a link and a bold template." resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"resource":"Image:Foobar.jpg"}}'/></a><figcaption>This is the image caption</figcaption></figure>
!! end
!! test
Ampersand in alt attribute (T206940)
-!! options
-parsoid = {
- "nativeGallery": true
-}
!! wikitext
[[File:Foobar.jpg|alt=&amp;]]
</div></li>
</ul>
!! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Image"><a href="./File:Foobar.jpg"><img alt="&amp;" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Image mw:ExpandedAttrs" about="#mwt1" data-mw='{"attribs":[["alt",{"html":"alt=<span typeof=\"mw:Entity\" data-parsoid='{\"src\":\"&amp;amp;\",\"srcContent\":\"&amp;\",\"dsr\":[22,27,null,null]}'>&amp;</span>amp;","txt":"&amp;"}]]}'><a href="./File:Foobar.jpg"><img alt="&amp;" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
<!-- consistency with gallery extension -->
-<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
-<li class="gallerybox">
-<div class="thumb"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img alt="&amp;" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt5" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
+<li class="gallerybox" style="width: 155px;">
+<div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image mw:ExpandedAttrs" data-mw='{"attribs":[["alt",{"html":"alt=<span typeof=\"mw:Entity\" data-parsoid='{\"src\":\"&amp;amp;\",\"srcContent\":\"&amp;\",\"dsr\":[109,114,null,null]}'>&amp;</span>amp;","txt":"&amp;"}]]}'><a href="./File:Foobar.jpg"><img alt="&amp;" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
<div class="gallerytext"></div>
</li>
</ul>
!! end
+## FIXME: The inconsistency in the gallery extension on the php side is T49646
+!! test
+Link with encoded pipe in alt option
+!! options
+parsoid={
+ "modes": ["wt2html", "html2html"]
+}
+!! wikitext
+[[File:Foobar.jpg|alt=http://testing.123?4=5|6|caption]]
+
+<!-- consistency with gallery extension -->
+<gallery>
+File:Foobar.jpg|alt=http://testing.123?4=5|6|caption
+</gallery>
+!! html/php+tidy
+<p><a href="/wiki/File:Foobar.jpg" class="image" title="caption"><img alt="http://testing.123?4=5|6" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" /></a>
+</p>
+<ul class="gallery mw-gallery-traditional">
+ <li class="gallerybox" style="width: 155px"><div style="width: 155px">
+ <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="http://testing.123?4=5&vert;6%7Ccaption" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" decoding="async" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
+ <div class="gallerytext">
+ </div>
+ </div></li>
+</ul>
+!! html/parsoid
+<p><figure-inline class="mw-default-size" typeof="mw:Image mw:ExpandedAttrs" about="#mwt1" data-parsoid='{"optList":[{"ck":"alt","ak":"alt=http://testing.123?4=5&vert;6"},{"ck":"caption","ak":"caption"}]}' data-mw='{"attribs":[["alt",{"html":"alt=<a rel=\"mw:ExtLink\" href=\"http://testing.123?4=5%7C6\" data-parsoid='{\"stx\":\"url\",\"a\":{\"href\":\"http://testing.123?4=5%7C6\"},\"sa\":{\"href\":\"http://testing.123?4=5&amp;vert;6\"},\"dsr\":[22,51,0,0]}'>http://testing.123?4=5%7C6</a>","txt":"http://testing.123?4=5|6"}]],"caption":"caption"}'><a href="./File:Foobar.jpg"><img alt="http://testing.123?4=5|6" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
+
+<!-- consistency with gallery extension -->
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt5" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image mw:ExpandedAttrs" data-mw='{"attribs":[["alt",{"html":"alt=<a rel=\"mw:ExtLink\" href=\"http://testing.123?4=5%7C6\" data-parsoid='{\"stx\":\"url\",\"a\":{\"href\":\"http://testing.123?4=5%7C6\"},\"sa\":{\"href\":\"http://testing.123?4=5&amp;vert;6\"},\"dsr\":[137,166,0,0]}'>http://testing.123?4=5%7C6</a>","txt":"http://testing.123?4=5|6"}]]}'><a href="./File:Foobar.jpg"><img alt="http://testing.123?4=5|6" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext">caption</div></li>
+!! end
+
!! test
Italics markup in alt attribute (T206940)
+!! options
+parsoid=wt2html,html2html
!! wikitext
[[File:Foobar.jpg|alt=''x''|caption]]
</div></li>
</ul>
!! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"alt","ak":"alt=''x''"},{"ck":"caption","ak":"caption"}]}' data-mw='{"caption":"caption"}'><a href="./File:Foobar.jpg"><img alt="x" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"alt":"x","resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"alt":"alt=''x''","resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Image mw:ExpandedAttrs" about="#mwt1" data-parsoid='{"optList":[{"ck":"alt","ak":"alt=''x''"},{"ck":"caption","ak":"caption"}]}' data-mw='{"attribs":[["alt",{"html":"alt=<i data-parsoid='{\"dsr\":[22,27,2,2]}'>x</i>","txt":"x"}]],"caption":"caption"}'><a href="./File:Foobar.jpg"><img alt="x" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
<!-- consistency with gallery extension -->
-<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{},"body":{"extsrc":"\nFile:Foobar.jpg|alt=''x''|caption\n"}}'>
-<li class="gallerybox">
-<div class="thumb"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img alt="x" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
-<div class="gallerytext">caption</div>
-</li>
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt5" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image mw:ExpandedAttrs" data-mw='{"attribs":[["alt",{"html":"alt=<i data-parsoid='{\"dsr\":[113,118,2,2]}'>x</i>","txt":"x"}]]}'><a href="./File:Foobar.jpg"><img alt="x" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext">caption</div></li>
</ul>
!! end
+## FIXME: This test can be dropped when Parsoid content versions 2.0.0 / 1.8.0
+## are no longer in storage.
!! test
Nowiki markup in alt attribute (T206940)
+!! options
+parsoid=html2wt
!! wikitext
[[File:Foobar.jpg|alt=<nowiki>''</nowiki>x<nowiki>''</nowiki>|caption]]
</div></li>
</ul>
!! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"alt","ak":"alt=<nowiki>''</nowiki>x<nowiki>''</nowiki>"},{"ck":"caption","ak":"caption"}],"dsr":[0,71,null,null]}' data-mw='{"caption":"caption"}'><a href="./File:Foobar.jpg"><img alt="''x''" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"alt":"''x''","resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"alt":"alt=<nowiki>''</nowiki>x<nowiki>''</nowiki>","resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Image mw:ExpandedAttrs" about="#mwt5" data-parsoid='{"optList":[{"ck":"alt","ak":"alt=<nowiki>''</nowiki>x<nowiki>''</nowiki>"},{"ck":"caption","ak":"caption"}]}' data-mw='{"attribs":[["alt",{"html":"alt=<span typeof=\"mw:Nowiki\" data-parsoid='{\"dsr\":[22,41,8,9]}'>''</span>x<span typeof=\"mw:Nowiki\" data-parsoid='{\"dsr\":[42,61,8,9]}'>''</span>","txt":"''x''"}]],"caption":"caption"}'><a href="./File:Foobar.jpg"><img alt="''x''" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" /></a></figure-inline></p>
<!-- consistency with gallery extension -->
-<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" data-mw='{"name":"gallery","attrs":{},"body":{"extsrc":"\nFile:Foobar.jpg|alt=<nowiki>''</nowiki>x<nowiki>''</nowiki>|caption\n"}}'>
-<li class="gallerybox">
-<div class="thumb"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img alt="''x''" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt13" data-mw='{"name":"gallery","attrs":{},"body":{"extsrc":"\nFile:Foobar.jpg|alt=<nowiki>''</nowiki>x<nowiki>''</nowiki>|caption\n"}}'>
+<li class="gallerybox" style="width: 155px;">
+<div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image mw:ExpandedAttrs" data-mw='{"attribs":[["alt",{"html":"alt=<span typeof=\"mw:Nowiki\" data-parsoid='{\"dsr\":[147,166,8,9]}'>''</span>x<span typeof=\"mw:Nowiki\" data-parsoid='{\"dsr\":[167,186,8,9]}'>''</span>","txt":"''x''"}]]}'><a href="./File:Foobar.jpg"><img alt="''x''" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
<div class="gallerytext">caption</div>
</li>
</ul>
!! test
Nowiki markup in alt attribute (edited html, no data-parsoid) (T206940)
-!! options
-parsoid = {
- "nativeGallery": true
-}
!! wikitext
[[File:Foobar.jpg|alt=<nowiki>''x''</nowiki>|caption]]
</div></li>
</ul>
!! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"caption"}'><a href="./File:Foobar.jpg"><img alt="''x''" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Image mw:ExpandedAttrs" about="#mwt3" data-mw='{"attribs":[["alt",{"html":"alt=<span typeof=\"mw:Nowiki\" data-parsoid='{\"dsr\":[22,44,8,9]}'>''x''</span>","txt":"''x''"}]],"caption":"caption"}'><a href="./File:Foobar.jpg"><img alt="''x''" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
<!-- consistency with gallery extension -->
-<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
-<li class="gallerybox">
-<div class="thumb"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img alt="''x''" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt9" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
+<li class="gallerybox" style="width: 155px;">
+<div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image mw:ExpandedAttrs" data-mw='{"attribs":[["alt",{"html":"alt=<span typeof=\"mw:Nowiki\" data-parsoid='{\"dsr\":[130,152,8,9]}'>''x''</span>","txt":"''x''"}]]}'><a href="./File:Foobar.jpg"><img alt="''x''" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
<div class="gallerytext">caption</div>
</li>
</ul>
!! end
+## FIXME: This test can be dropped when Parsoid content versions 2.0.0 / 1.8.0
+## are no longer in storage.
!! test
Ampersand in link attribute (T206940)
+!! options
+parsoid=html2wt
!! wikitext
[[File:Foobar.jpg|link=Foo & bar]]
!! test
Ampersand in link attribute (edited html, no data-parsoid) (T206940)
-!! options
-parsoid = {
- "nativeGallery": true
-}
!! wikitext
[[File:Foobar.jpg|link=Foo_&_bar]]
!! test
Italics markup in link attribute (T206940)
+!! options
+parsoid=wt2html,html2html
!! wikitext
[[Foo''s bar''s]]
<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"link","ak":"link=''Main Page''"},{"ck":"caption","ak":"caption2"}]}' data-mw='{"caption":"caption2"}'><a href="./Main_Page" data-parsoid='{"a":{"href":"./Main_Page"},"sa":{"href":"link=''Main Page''"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
<!-- consistency with gallery extension -->
-<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" data-mw='{"name":"gallery","attrs":{},"body":{"extsrc":"\nFile:Foobar.jpg|link=Foo''s bar''s|caption1\nFile:Foobar.jpg|link=''Main Page''|caption2\n"}}'>
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
<li class="gallerybox">
<div class="thumb"><figure-inline typeof="mw:Image"><a href="./Foos_bars"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
<div class="gallerytext">caption1</div>
</ul>
!! end
+## FIXME: This test can be dropped when Parsoid content versions 2.0.0 / 1.8.0
+## are no longer in storage.
!! test
Nowiki markup in link attribute (T206940)
+!! options
+parsoid=html2wt
!! wikitext
[[File:Foobar.jpg|link=Foo<nowiki>''</nowiki>s_bar<nowiki>''</nowiki>s|caption]]
!! test
Nowiki markup in link attribute (edited html, no data-parsoid) (T206940)
-!! options
-parsoid = {
- "nativeGallery": true
-}
!! wikitext
[[File:Foobar.jpg|link=Foo<nowiki>''s_bar''</nowiki>s|caption]]
<p><figure-inline class="mw-default-size" typeof="mw:Image"><a href="https://example.com?foo&params=bar"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
<!-- consistency with gallery extension -->
-<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" data-mw='{"name":"gallery","attrs":{},"body":{"extsrc":"\nFile:Foobar.jpg|link=https://example.com?foo&params=bar\n"}}'>
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
<li class="gallerybox">
<div class="thumb"><figure-inline typeof="mw:Image"><a href="https://example.com?foo&params=bar"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
<div class="gallerytext"></div>
!! html/php
<div class="thumb tright"><div class="thumbinner" style="width:52px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" decoding="async" width="50" height="6" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/75px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/100px-Foobar.jpg 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div></div></div></div>
!! html/parsoid
-<figure typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="6" width="50"/></a></figure>
+<figure typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="6" width="50"/></a><figcaption></figcaption></figure>
!! end
!! test
<div class="thumb tright"><div class="thumbinner" style="width:1943px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" class="thumbimage" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div></div></div></div>
<div class="thumb tright"><div class="thumbinner" style="width:2002px;"><a href="/wiki/File:Foobar.svg" class="image"><img alt="Foobar.svg" src="http://example.com/images/thumb/f/ff/Foobar.svg/2000px-Foobar.svg.png" decoding="async" width="2000" height="1500" class="thumbimage" srcset="http://example.com/images/thumb/f/ff/Foobar.svg/3000px-Foobar.svg.png 1.5x, http://example.com/images/thumb/f/ff/Foobar.svg/4000px-Foobar.svg.png 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.svg" class="internal" title="Enlarge"></a></div></div></div></div>
!! html/parsoid
-<figure typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure>
-<figure typeof="mw:Image/Thumb"><a href="./File:Foobar.svg"><img resource="./File:Foobar.svg" src="//example.com/images/thumb/f/ff/Foobar.svg/2000px-Foobar.svg.png" data-file-width="240" data-file-height="180" data-file-type="drawing" height="1500" width="2000"/></a></figure>
+<figure typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption></figcaption></figure>
+<figure typeof="mw:Image/Thumb"><a href="./File:Foobar.svg"><img resource="./File:Foobar.svg" src="//example.com/images/thumb/f/ff/Foobar.svg/2000px-Foobar.svg.png" data-file-width="240" data-file-height="180" data-file-type="drawing" height="1500" width="2000"/></a><figcaption></figcaption></figure>
!! end
!! test
<div class="thumb tright"><div class="thumbinner" style="width:1943px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" class="thumbimage" /></a> <div class="thumbcaption"></div></div></div>
<div class="thumb tright"><div class="thumbinner" style="width:1943px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" class="thumbimage" /></a> <div class="thumbcaption"></div></div></div>
!! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Frame"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure>
-<figure typeof="mw:Image/Frame"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure>
-<figure typeof="mw:Image/Frame"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure>
-<figure typeof="mw:Image/Frame"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure>
+<figure class="mw-default-size" typeof="mw:Image/Frame"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption></figcaption></figure>
+<figure typeof="mw:Image/Frame"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption></figcaption></figure>
+<figure typeof="mw:Image/Frame"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption></figcaption></figure>
+<figure typeof="mw:Image/Frame"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption></figcaption></figure>
!! end
###################
<p><a href="/index.php?title=Special:Upload&wpDestFile=7%25_solution.gif" class="new" title="File:7% solution.gif">7% solution</a>
</p>
!! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-parsoid='{"optList":[{"ck":"bogus","ak":"manualthumb=7%25 solution.gif"},{"ck":"link","ak":"link=7%25 solution"},{"ck":"caption","ak":"[[7%25 solution]]"}]}' data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}],"caption":"<a rel=\"mw:WikiLink\" href=\"./7%25_solution\" title=\"7% solution\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./7%25_solution\"},\"sa\":{\"href\":\"7%25 solution\"},\"dsr\":[74,91,2,2]}'>7% solution</a>"}'><a href="./7%25_solution" data-parsoid='{"a":{"href":"./7%25_solution"},"sa":{"href":"link=7%25 solution"}}'><img resource="./File:7%25_solution.gif" src="./Special:FilePath/7%25_solution.gif" height="220" width="220" data-parsoid='{"a":{"resource":"./File:7%25_solution.gif","height":"220","width":"220"},"sa":{"resource":"File:7%25 solution.gif"}}'/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-parsoid='{"optList":[{"ck":"bogus","ak":"manualthumb=7%25 solution.gif"},{"ck":"link","ak":"link=7%25 solution"},{"ck":"caption","ak":"[[7%25 solution]]"}]}' data-mw='{"attribs":[["link",{"txt":"7%25 solution"}]],"caption":"<a rel=\"mw:WikiLink\" href=\"./7%25_solution\" title=\"7% solution\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./7%25_solution\"},\"sa\":{\"href\":\"7%25 solution\"},\"dsr\":[74,91,2,2]}'>7% solution</a>","errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/7%25_solution.gif"><span resource="./File:7%25_solution.gif" data-parsoid='{"a":{"resource":"./File:7%25_solution.gif"},"sa":{"resource":"File:7%25 solution.gif"}}'>File:7% solution.gif</span></a></figure-inline></p>
!! end
!! test
</p>
!! end
+## FIXME: Parsoid needs to learn about this flag.
!! test
Missing image with uploads disabled
!! options
<p><a href="/wiki/File:Foobaz.jpg" title="File:Foobaz.jpg">File:Foobaz.jpg</a>
</p>
!! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./File:Foobaz.jpg"><img resource="./File:Foobaz.jpg" src="./Special:FilePath/Foobaz.jpg" height="220" width="220"/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Foobaz.jpg"><span resource="./File:Foobaz.jpg">File:Foobaz.jpg</span></a></figure-inline></p>
!! end
# Parsoid-specific testing for images
<p><a href="/index.php?title=Special:Upload&wpDestFile=No_such.jpg" class="new" title="File:No such.jpg">File:No such.jpg</a>
</p>
!! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./File:No_such.jpg"><img resource="./File:No_such.jpg" src="./Special:FilePath/No_such.jpg" height="220" width="220"/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/No_such.jpg"><span resource="./File:No_such.jpg">File:No such.jpg</span></a></figure-inline></p>
!! end
!! test
!! html/parsoid
<p><meta typeof="mw:LanguageVariant" data-mw-variant='{"add":true,"oneway":[{"f":"foAjrjvi","l":"sr-el","t":"\" onload=\"alert(1)\" data-foo=\""}]}'/></p>
-<p><figure-inline class="mw-default-size" typeof="mw:Image"><a href="./Датотека:Foobar.jpg"><img alt="foAjrjvi" resource="./Датотека:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"alt":"foAjrjvi","resource":"./Датотека:Foobar.jpg","height":"220","width":"1941"},"sa":{"alt":"alt=-{}-foAjrjvi-{}-","resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Image mw:ExpandedAttrs" about="#mwt1" data-mw='{"attribs":[["alt",{"html":"alt=<span typeof=\"mw:LanguageVariant\" data-mw-variant='{\"disabled\":{\"t\":\"\"}}' data-parsoid='{\"fl\":[],\"dsr\":[76,80,null,2]}'></span>foAjrjvi<span typeof=\"mw:LanguageVariant\" data-mw-variant='{\"disabled\":{\"t\":\"\"}}' data-parsoid='{\"fl\":[],\"dsr\":[88,92,null,2]}'></span>","txt":"foAjrjvi"}]]}'><a href="./Датотека:Foobar.jpg"><img alt="foAjrjvi" resource="./Датотека:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./Датотека:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
!! end
!! test
!! html/php
<div class="thumb tright"><div class="thumbinner" style="width:182px;">Error creating thumbnail: <div class="thumbcaption"></div></div></div>
!! html/parsoid
-<figure class="mw-default-size" typeof="mw:Error mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"manualthumb","ak":"thumbnail= "}]}' data-mw='{"errors":[{"key":"apierror-invalidtitle","message":"Invalid thumbnail title.","params":{"name":""}}],"thumb":""}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{"href":"Image:foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="./Special:FilePath/Foobar.jpg" height="220" width="220" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"220"},"sa":{"resource":"Image:foobar.jpg"}}'/></a></figure>
+<figure class="mw-default-size" typeof="mw:Error mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"manualthumb","ak":"thumbnail= "}]}' data-mw='{"attribs":[["manualthumb",{"txt":""}]],"errors":[{"key":"apierror-invalidtitle","message":"Invalid thumbnail title.","params":{"name":""}}]}'><a href="./Special:FilePath/Foobar.jpg"><span resource="./File:Foobar.jpg" data-parsoid='{"a":{"resource":"./File:Foobar.jpg"},"sa":{"resource":"Image:foobar.jpg"}}'>File:Foobar.jpg</span></a><figcaption></figcaption></figure>
!! end
# Parsoid will emit the newline literally in wt2wt; see next test case.
</div></li>
</ul>
!! html/parsoid
-<ul class="gallery mw-gallery-traditional" type="123" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{"type":"123","summary":"345"},"body":{"extsrc":"\nFile:File:Foobar.jpg\n"}}'>
-<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:File:Foobar.jpg"><img resource="./File:File:Foobar.jpg" src="./Special:FilePath/File:Foobar.jpg" height="120" width="120"/></a></figure-inline></div><div class="gallerytext"></div></li>
+<ul class="gallery mw-gallery-traditional" type="123" typeof="mw:Extension/gallery" about="#mwt3" data-mw='{"name":"gallery","attrs":{"type":"123","summary":"345"},"body":{}}'>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/File:Foobar.jpg"><span resource="./File:File:Foobar.jpg" data-width="120" data-height="120">File:File:Foobar.jpg</span></a></figure-inline></div><div class="gallerytext"></div></li>
</ul>
!! end
Gallery
!! options
parsoid={
- "modes": ["wt2html"],
- "nativeGallery": true
+ "modes": ["wt2html"]
}
!! wikitext
<gallery>
</ul>
!! html/parsoid
<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt3" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
-<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:Image1.png"><img resource="./File:Image1.png" src="./Special:FilePath/Image1.png" height="120" width="120"/></a></figure-inline></div><div class="gallerytext"></div></li>
-<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:Image2.gif"><img resource="./File:Image2.gif" src="./Special:FilePath/Image2.gif" height="120" width="120"/></a></figure-inline></div><div class="gallerytext"></div></li>
-<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:Image3"><img resource="./File:Image3" src="./Special:FilePath/Image3" height="120" width="120"/></a></figure-inline></div><div class="gallerytext"></div></li>
-<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:Image4"><img resource="./File:Image4" src="./Special:FilePath/Image4" height="300" width="300"/></a></figure-inline></div><div class="gallerytext"></div></li>
-<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:Image5.svg"><img resource="./File:Image5.svg" src="./Special:FilePath/Image5.svg" height="120" width="120"/></a></figure-inline></div><div class="gallerytext"> <a rel="mw:ExtLink" class="external free" href="http://///////">http://///////</a></div></li>
-<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:*_image6"><img resource="./File:*_image6" src="./Special:FilePath/*_image6" height="120" width="120"/></a></figure-inline></div><div class="gallerytext"></div></li>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Image1.png"><span resource="./File:Image1.png" data-width="120" data-height="120">File:Image1.png</span></a></figure-inline></div><div class="gallerytext"></div></li>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Image2.gif"><span resource="./File:Image2.gif" data-width="120" data-height="120">File:Image2.gif</span></a></figure-inline></div><div class="gallerytext"></div></li>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Image3"><span resource="./File:Image3" data-width="120" data-height="120">File:Image3</span></a></figure-inline></div><div class="gallerytext"></div></li>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Image4"><span resource="./File:Image4" data-width="300">File:Image4</span></a></figure-inline></div><div class="gallerytext"></div></li>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Image5.svg"><span resource="./File:Image5.svg" data-width="120" data-height="120">File:Image5.svg</span></a></figure-inline></div><div class="gallerytext"> <a rel="mw:ExtLink" class="external free" href="http://///////">http://///////</a></div></li>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/*_image6"><span resource="./File:*_image6" data-width="120" data-height="120">File:* image6</span></a></figure-inline></div><div class="gallerytext"></div></li>
</ul>
!! end
Gallery (with options, html)
!! options
parsoid={
- "modes": ["wt2html", "html2html"],
- "nativeGallery": true
+ "modes": ["wt2html", "html2html"]
}
!! wikitext
<gallery widths="70px" heights="40px" perrow="2" caption="Foo [[Main Page]]">
!! html/parsoid
<ul class="gallery mw-gallery-traditional" style="max-width: 226px; _width: 226px;" typeof="mw:Extension/gallery" about="#mwt3" data-mw='{"name":"gallery","attrs":{"widths":"70px","heights":"40px","perrow":"2"},"body":{}}'>
<li class="gallerycaption">Foo <a rel="mw:WikiLink" href="./Main_Page" title="Main Page">Main Page</a></li>
-<li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:Nonexistent.jpg"><img resource="./File:Nonexistent.jpg" src="./Special:FilePath/Nonexistent.jpg" height="40" width="70"/></a></figure-inline></div><div class="gallerytext">caption</div></li>
-<li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:Nonexistent.jpg"><img resource="./File:Nonexistent.jpg" src="./Special:FilePath/Nonexistent.jpg" height="40" width="70"/></a></figure-inline></div><div class="gallerytext"></div></li>
+<li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Nonexistent.jpg"><span resource="./File:Nonexistent.jpg" data-width="70" data-height="40">File:Nonexistent.jpg</span></a></figure-inline></div><div class="gallerytext">caption</div></li>
+<li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Nonexistent.jpg"><span resource="./File:Nonexistent.jpg" data-width="70" data-height="40">File:Nonexistent.jpg</span></a></figure-inline></div><div class="gallerytext"></div></li>
<li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/70px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="8" width="70"/></a></figure-inline></div><div class="gallerytext">some <b>caption</b> <a rel="mw:WikiLink" href="./Main_Page" title="Main Page">Main Page</a></div></li>
<li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/70px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="8" width="70"/></a></figure-inline></div><div class="gallerytext"></div></li>
<li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img alt="This is a foo-bar." resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/70px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="8" width="70"/></a></figure-inline></div><div class="gallerytext">blabla.</div></li>
</ul>
!! end
+## FIXME: This test can be dropped when Parsoid content versions 2.0.0 / 1.8.0
+## are no longer in storage.
!! test
Gallery (with options, extsrc)
!! options
-parsoid={
- "nativeGallery": false
-}
+parsoid=html2wt
!! wikitext
<gallery widths="70px" heights="40px" perrow="2" caption="Foo [[Main Page]]">
File:Nonexistent.jpg|caption
</div></li>
</ul>
!! html/parsoid
-<ul class="gallery mw-gallery-traditional" style="max-width: 226px; _width: 226px;" typeof="mw:Extension/gallery" about="#mwt3" data-mw='{"name":"gallery","attrs":{"widths":"70px","heights":"40px","perrow":"2","caption":"Foo [[Main Page]]"},"body":{"extsrc":"\nFile:Nonexistent.jpg|caption\nFile:Nonexistent.jpg\nimage:foobar.jpg|some '''caption''' [[Main Page]]\nimage:foobar.jpg\nimage:foobar.jpg|Blabla|alt=This is a foo-bar.|blabla.\n"}}'>
+<ul class="gallery mw-gallery-traditional" style="max-width: 226px; _width: 226px;" typeof="mw:Extension/gallery" about="#mwt3" data-mw='{"name":"gallery","attrs":{"widths":"70px","heights":"40px","perrow":"2","caption":"Foo [[Main Page]]"},"body":{"extsrc":"\nFile:Nonexistent.jpg|caption\nFile:Nonexistent.jpg\nimage:foobar.jpg|some '''caption''' [[Main Page]]\nimage:foobar.jpg\nimage:foobar.jpg|Blabla|alt=This is a foo-bar.|blabla.\n"}}'>
<li class="gallerycaption">Foo <a rel="mw:WikiLink" href="./Main_Page" title="Main Page">Main Page</a></li>
-<li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:Nonexistent.jpg"><img resource="./File:Nonexistent.jpg" src="./Special:FilePath/Nonexistent.jpg" height="40" width="70"/></a></figure-inline></div><div class="gallerytext">caption</div></li>
-<li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:Nonexistent.jpg"><img resource="./File:Nonexistent.jpg" src="./Special:FilePath/Nonexistent.jpg" height="40" width="70"/></a></figure-inline></div><div class="gallerytext"></div></li>
+<li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Nonexistent.jpg"><span resource="./File:Nonexistent.jpg" data-width="70" data-height="40">File:Nonexistent.jpg</span></a></figure-inline></div><div class="gallerytext">caption</div></li>
+<li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Nonexistent.jpg"><span resource="./File:Nonexistent.jpg" data-width="70" data-height="40">File:Nonexistent.jpg</span></a></figure-inline></div><div class="gallerytext"></div></li>
<li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/70px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="8" width="70"/></a></figure-inline></div><div class="gallerytext">some <b>caption</b> <a rel="mw:WikiLink" href="./Main_Page" title="Main Page">Main Page</a></div></li>
<li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/70px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="8" width="70"/></a></figure-inline></div><div class="gallerytext"></div></li>
<li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img alt="This is a foo-bar." resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/70px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="8" width="70"/></a></figure-inline></div><div class="gallerytext">blabla.</div></li>
</div></li>
</ul>
!! html/parsoid
-<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{"widths":"70","heights":"40"},"body":{"extsrc":"\nFile:Foobar.jpg\n"}}'>
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{"widths":"70","heights":"40"},"body":{}}'>
<li class="gallerybox" style="width: 105px;"><div class="thumb" style="width: 100px; height: 70px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/70px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="8" width="70"/></a></figure-inline></div><div class="gallerytext"></div></li>
</ul>
!! end
</div></li>
</ul>
!! html/parsoid
-<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{"widths":"70em","heights":"40em"},"body":{"extsrc":"\nFile:Foobar.jpg\n"}}'>
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{"widths":"70em","heights":"40em"},"body":{}}'>
<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext"></div></li>
</ul>
!! end
Gallery with link that has fragment
!! options
parsoid={
- "modes": ["wt2html", "html2html"],
- "nativeGallery": true
+ "modes": ["wt2html", "html2html"]
}
!! wikitext
<gallery>
!! test
Gallery with template inside caption
-!! options
-parsoid={
- "nativeGallery": true
-}
!! wikitext
<gallery caption="{{echo|hi}}">
File:Foobar.jpg|{{echo|ho}}
!! test
Gallery with wikitext inside gallery caption
+!! options
+parsoid={
+ "modes": ["wt2html", "html2html"]
+}
!! wikitext
-<gallery caption="# List item
+<gallery caption="# This should not be a list item
Text '''bold''' [[link]] {{ns:-1}}
</gallery>
!! html/php
<ul class="gallery mw-gallery-traditional">
- <li class='gallerycaption'># List item Text <b>bold</b> <a href="/index.php?title=Link&action=edit&redlink=1" class="new" title="Link (page does not exist)">link</a> Special <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" decoding="async" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>File in gallery caption</div></div></div></li>
+ <li class='gallerycaption'># This should not be a list item Text <b>bold</b> <a href="/index.php?title=Link&action=edit&redlink=1" class="new" title="Link (page does not exist)">link</a> Special <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" decoding="async" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>File in gallery caption</div></div></div></li>
<li class="gallerybox" style="width: 155px"><div style="width: 155px">
<div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" decoding="async" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
<div class="gallerytext">
</div>
</div></li>
</ul>
+!! html/parsoid
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt3" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
+<li class="gallerycaption"># This should not be a list item Text <b>bold</b> <a rel="mw:WikiLink" href="./Link" title="Link">link</a> <span about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"ns:-1","function":"ns"},"params":{},"i":0}}]}'>-1</span> <figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>File in gallery caption</figcaption></figure></li>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext">Image caption</div></li>
+</ul>
!! end
!! test
Gallery with wikitext inside caption
-!! options
-parsoid={
- "nativeGallery": true
-}
!! wikitext
<gallery>
File:Foobar.jpg|alt=galleryalt|[[File:Foobar.jpg|alt=inneralt|20x20px|desc]]
!! test
Gallery (with showfilename option)
-!! options
-parsoid={
- "nativeGallery": true
-}
!! wikitext
<gallery showfilename="">
File:Nonexistent.jpg|caption
</ul>
!! html/parsoid
<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt3" data-mw='{"name":"gallery","attrs":{"showfilename":""},"body":{}}'>
-<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:Nonexistent.jpg"><img resource="./File:Nonexistent.jpg" src="./Special:FilePath/Nonexistent.jpg" height="120" width="120"/></a></figure-inline></div><div class="gallerytext"><a href="./File:Nonexistent.jpg" class="galleryfilename galleryfilename-truncate" title="File:Nonexistent.jpg">File:Nonexistent.jpg</a>caption</div></li>
-<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:Nonexistent.jpg"><img resource="./File:Nonexistent.jpg" src="./Special:FilePath/Nonexistent.jpg" height="120" width="120"/></a></figure-inline></div><div class="gallerytext"><a href="./File:Nonexistent.jpg" class="galleryfilename galleryfilename-truncate" title="File:Nonexistent.jpg">File:Nonexistent.jpg</a></div></li>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Nonexistent.jpg"><span resource="./File:Nonexistent.jpg" data-width="120" data-height="120">File:Nonexistent.jpg</span></a></figure-inline></div><div class="gallerytext"><a href="./File:Nonexistent.jpg" class="galleryfilename galleryfilename-truncate" title="File:Nonexistent.jpg">File:Nonexistent.jpg</a>caption</div></li>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Nonexistent.jpg"><span resource="./File:Nonexistent.jpg" data-width="120" data-height="120">File:Nonexistent.jpg</span></a></figure-inline></div><div class="gallerytext"><a href="./File:Nonexistent.jpg" class="galleryfilename galleryfilename-truncate" title="File:Nonexistent.jpg">File:Nonexistent.jpg</a></div></li>
<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext"><a href="./File:Foobar.jpg" class="galleryfilename galleryfilename-truncate" title="File:Foobar.jpg">File:Foobar.jpg</a>some <b>caption</b> <a rel="mw:WikiLink" href="./Main_Page" title="Main Page">Main Page</a></div></li>
<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext"><a href="./File:Foobar.jpg" class="galleryfilename galleryfilename-truncate" title="File:Foobar.jpg">File:Foobar.jpg</a></div></li>
</ul>
Gallery (with namespace-less filenames)
!! options
parsoid={
- "modes": ["wt2html", "html2html"],
- "nativeGallery": true
+ "modes": ["wt2html", "html2html"]
}
!! wikitext
<gallery>
</div></li>
</ul>
!! html/parsoid
-<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
-<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:Nonexistent.jpg"><img resource="./File:Nonexistent.jpg" src="./Special:FilePath/Nonexistent.jpg" height="120" width="120"/></a></figure-inline></div><div class="gallerytext"></div></li>
-<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image"><a href="./File:Nonexistent.jpg"><img resource="./File:Nonexistent.jpg" src="./Special:FilePath/Nonexistent.jpg" height="120" width="120"/></a></figure-inline></div><div class="gallerytext"></div></li>
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt3" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Nonexistent.jpg"><span resource="./File:Nonexistent.jpg" data-width="120" data-height="120">File:Nonexistent.jpg</span></a></figure-inline></div><div class="gallerytext"></div></li>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Nonexistent.jpg"><span resource="./File:Nonexistent.jpg" data-width="120" data-height="120">File:Nonexistent.jpg</span></a></figure-inline></div><div class="gallerytext"></div></li>
<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext"></div></li>
<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext"></div></li>
</ul>
!! test
Gallery override link with wikilink (T36852)
-!! options
-parsoid={
- "nativeGallery": true
-}
!! wikitext
<gallery>
File:Foobar.jpg|alt=galleryalt|link=Wikilink
!! test
Gallery override link with absolute external link (T36852)
-!! options
-parsoid={
- "nativeGallery": true
-}
!! wikitext
<gallery>
File:Foobar.jpg|alt=galleryalt|link=http://www.example.org
</ul>
!! end
+## Putting the caption at the end here runs into T49646 on the php side
+## so reducing the modes this runs in Parsoid
!! test
Gallery override link with absolute external link with LanguageConverter
!! options
language=zh
+parsoid=wt2html,html2html
!! wikitext
<gallery>
File:foobar.jpg|caption|alt=galleryalt|link=http://www.example.org
</div></li>
</ul>
!! html/parsoid
-<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{},"body":{"extsrc":"\nFile:foobar.jpg|caption|alt=galleryalt|link=http://www.example.org\n"}}'>
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image"><a href="http://www.example.org"><img alt="galleryalt" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext">caption</div></li>
</ul>
!! end
Gallery override link with malicious javascript (T36852)
!! options
parsoid={
- "modes": ["wt2html", "html2html"],
- "nativeGallery": true
+ "modes": ["wt2html", "html2html"]
}
!! wikitext
<gallery>
</ul>
!! end
-# Note that parsoid uses the invalid link as a caption, PHP does not.
!! test
Gallery with invalid title as link (T45964)
!! options
parsoid={
- "modes": ["wt2html", "html2html"],
- "nativeGallery": true
+ "modes": ["wt2html", "html2html"]
}
!! wikitext
<gallery>
</div></li>
</ul>
!! html/parsoid
-<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
-<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext">link=<</div></li>
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt3" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image" data-mw='{"attribs":[["link",{"txt":"<"}]]}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext"></div></li>
</ul>
!! end
Serialize gallery without attrs in data-mw
!! options
parsoid={
- "modes": ["html2wt"],
- "nativeGallery": true
+ "modes": ["html2wt"]
}
!! html/parsoid
<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","body":{}}'>
!! test
Gallery with class and style attributes
-!! options
-parsoid={
- "nativeGallery": true
-}
!! wikitext
<gallery class="center" style="text-align: center;">
File:Foobar.jpg
!! test
Gallery in slideshow mode
-!! options
-parsoid={
- "nativeGallery": true
-}
!! wikitext
<gallery mode="slideshow" showthumbnails="">
File:Foobar.jpg
</ul>
!! end
+!! test
+Gallery in packed mode
+!! wikitext
+<gallery mode="packed">
+File:Foobar.jpg
+</gallery>
+!! html/php
+<ul class="gallery mw-gallery-packed">
+ <li class="gallerybox" style="width: 1061.3333333333px"><div style="width: 1061.3333333333px">
+ <div class="thumb" style="width: 1059.3333333333px;"><div style="margin:0px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/1589px-Foobar.jpg" decoding="async" width="1060" height="120" srcset="http://example.com/images/3/3a/Foobar.jpg 1.5x" /></a></div></div>
+ <div class="gallerytext">
+ </div>
+ </div></li>
+</ul>
+!! html/parsoid
+<ul class="gallery mw-gallery-packed" typeof="mw:Extension/gallery" about="#mwt3" data-parsoid='{"dsr":[0,50,23,10]}' data-mw='{"name":"gallery","attrs":{"mode":"packed"},"body":{}}'>
+<li class="gallerybox" style="width: 1061px;"><div class="thumb" style="width: 1059px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/1589px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="120" width="1059"/></a></figure-inline></div><div class="gallerytext"></div></li>
+</ul>
+!! end
+
!! test
Serialize gallery image captions on a line
!! options
parsoid={
- "modes": ["html2wt"],
- "nativeGallery": true
+ "modes": ["html2wt"]
}
!! html/parsoid
<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
!! html/php
<div class="center"><div class="floatnone"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" /></a></div></div>
!! html/parsoid
-<figure class="mw-default-size mw-halign-center" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"center","ak":"centre"}]}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"Image:foobar.jpg"}}'/></a></figure>
+<figure class="mw-default-size mw-halign-center" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"center","ak":"centre"}]}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"Image:foobar.jpg"}}'/></a><figcaption></figcaption></figure>
!! end
!! test
!! html/php
<div class="floatnone"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" /></a></div>
!! html/parsoid
-<figure class="mw-default-size mw-halign-none" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"Image:foobar.jpg"}}'/></a></figure>
+<figure class="mw-default-size mw-halign-none" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"Image:foobar.jpg"}}'/></a><figcaption></figcaption></figure>
!! end
!! test
<p><figure-inline typeof="mw:Image" data-parsoid='{"optList":[{"ck":"width","ak":" 640px"}]}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/640px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="73" width="640" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"73","width":"640"},"sa":{"resource":"Image:foobar.jpg"}}'/></a></figure-inline></p>
!! end
+## FIXME: Parsoid mocking should include the page in the url to catch regressions
!! test
Image with page parameter
!! options
<p><a href="/index.php?title=File:LoremIpsum.djvu&page=2" class="image"><img alt="LoremIpsum.djvu" src="http://example.com/images/thumb/5/5f/LoremIpsum.djvu/page2-2480px-LoremIpsum.djvu.jpg" decoding="async" width="2480" height="3508" srcset="http://example.com/images/thumb/5/5f/LoremIpsum.djvu/page2-3720px-LoremIpsum.djvu.jpg 1.5x, http://example.com/images/thumb/5/5f/LoremIpsum.djvu/page2-4960px-LoremIpsum.djvu.jpg 2x" /></a>
</p>
!! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"page","ak":"page=2"}]}' data-mw='{"page":"2"}'><a href="./File:LoremIpsum.djvu" data-parsoid='{"a":{"href":"./File:LoremIpsum.djvu"},"sa":{"href":"File:LoremIpsum.djvu"}}'><img resource="./File:LoremIpsum.djvu" src="//example.com/images/5/5f/LoremIpsum.djvu" data-file-width="2480" data-file-height="3508" data-file-type="bitmap" height="3508" width="2480" data-parsoid='{"a":{"resource":"./File:LoremIpsum.djvu","height":"3508","width":"2480"},"sa":{"resource":"File:LoremIpsum.djvu"}}'/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Image" data-mw='{"attribs":[["page",{"txt":"2"}]]}'><a href="./File:LoremIpsum.djvu" data-parsoid='{"a":{"href":"./File:LoremIpsum.djvu"},"sa":{"href":"File:LoremIpsum.djvu"}}'><img resource="./File:LoremIpsum.djvu" src="//example.com/images/5/5f/LoremIpsum.djvu" data-file-width="2480" data-file-height="3508" data-file-type="bitmap" height="3508" width="2480" data-parsoid='{"a":{"resource":"./File:LoremIpsum.djvu","height":"3508","width":"2480"},"sa":{"resource":"File:LoremIpsum.djvu"}}'/></a></figure-inline></p>
!! end
!! test
Don't break gallery if language converter markup is inside.
!! options
language=zh
+parsoid=wt2html,html2html
!! wikitext
<gallery>
-File:foobar.jpg|[[File:foobar.jpg|20px|desc|alt=-{R|foo}-|-{R|bar}-]]|alt=-{R|bat}-
-File:foobar.jpg|{{Test|unamedParam|alt=-{R|param}-}}|alt=galleryalt
+File:Foobar.jpg|alt=-{R|bat}-|[[File:foobar.jpg|20px|desc|alt=-{R|foo}-|-{R|bar}-]]
+File:Foobar.jpg|alt=galleryalt|{{Test|unamedParam|alt=-{R|param}-}}
</gallery>
!! html/php
<ul class="gallery mw-gallery-traditional">
</div></li>
</ul>
!! html/parsoid
-<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt6" data-mw='{"name":"gallery","attrs":{},"body":{"extsrc":"\nFile:foobar.jpg|[[File:foobar.jpg|20px|desc|alt=-{R|foo}-|-{R|bar}-]]|alt=-{R|bat}-\nFile:foobar.jpg|{{Test|unamedParam|alt=-{R|param}-}}|alt=galleryalt\n"}}'>
-<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img alt="" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext"><figure-inline typeof="mw:Image" data-mw='{"caption":"<span typeof=\"mw:LanguageVariant\" data-mw-variant='{\"disabled\":{\"t\":\"bar\"}}' data-parsoid='{\"fl\":[\"R\"],\"dsr\":[68,77,null,2]}'></span>"}'><a href="./File:Foobar.jpg"><img alt="" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/20px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="2" width="20"/></a></figure-inline></div></li>
-<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img alt="galleryalt" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext"><span about="#mwt4" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"Test","href":"./Template:Test"},"params":{"1":{"wt":"unamedParam"},"alt":{"wt":"-{R|param}-"}},"i":0}}]}'>This is a test template</span></div></li>
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt6" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image mw:ExpandedAttrs" data-mw='{"attribs":[["alt",{"html":"alt=<span typeof=\"mw:LanguageVariant\" data-mw-variant='{\"disabled\":{\"t\":\"bat\"}}' data-parsoid='{\"fl\":[\"R\"],\"dsr\":[84,93,null,2]}'></span>","txt":""}]]}'><a href="./File:Foobar.jpg"><img alt="" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext"><figure-inline typeof="mw:Image mw:ExpandedAttrs" about="#mwt3" data-mw='{"attribs":[["alt",{"html":"alt=<span typeof=\"mw:LanguageVariant\" data-mw-variant='{\"disabled\":{\"t\":\"foo\"}}' data-parsoid='{\"fl\":[\"R\"],\"dsr\":[58,67,null,2]}'></span>","txt":""}]],"caption":"<span typeof=\"mw:LanguageVariant\" data-mw-variant='{\"disabled\":{\"t\":\"bar\"}}' data-parsoid='{\"fl\":[\"R\"],\"dsr\":[68,77,null,2]}'></span>"}'><a href="./File:Foobar.jpg"><img alt="" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/20px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="2" width="20"/></a></figure-inline></div></li>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img alt="galleryalt" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext"><span about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"Test","href":"./Template:Test"},"params":{"1":{"wt":"unamedParam"},"alt":{"wt":"-{R|param}-"}},"i":0}}]}'>This is a test template</span></div></li>
</ul>
!! end
[[File:Bad.jpg]]
!! html/php+disabled
!! html/parsoid
-<p><span class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"bad-image","message":"This image is blacklisted in this context."}]}'><a href="./File:Bad.jpg"><img resource="./File:Bad.jpg" height="220" width="220"/></a></span></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Bad.jpg"><span resource="./File:Bad.jpg">File:Bad.jpg</span></a></figure-inline></p>
!! end
!! test
</p>
!! html/parsoid
<p>Foo bar
-<span class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"bad-image","message":"This image is blacklisted in this context."}]}'><a href="./File:Bad.jpg"><img resource="./File:Bad.jpg" height="220" width="220"/></a></span>
+<figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Bad.jpg"><span resource="./File:Bad.jpg">File:Bad.jpg</span></a></figure-inline>
Bar foo</p>
!! end
!! test
Strip reserved data attributes
!! wikitext
-<div data-mw="foo" data-parsoid="bar" data-mw-someext="baz" data-ok="fred" data-ooui="xyzzy" data-bad:ns="ns">d</div>
+<div data-mw="foo" data-parsoid="bar" data-mw-someext="baz" data-ok="fred" data-object-id="123" data-ooui="xyzzy" data-bad:ns="ns">d</div>
!! html/php
-<div data-ok="fred">d</div>
+<div data-ok="fred" data-object-id="123">d</div>
!! html/parsoid
-<div data-x-data-mw="foo" data-x-data-parsoid="bar" data-x-data-mw-someext="baz" data-ok="fred" data-parsoid='{"stx":"html","a":{"data-ooui":null,"data-bad:ns":null},"sa":{"data-ooui":"xyzzy","data-bad:ns":"ns"}}'>d</div>
+<div data-x-data-mw="foo" data-x-data-parsoid="bar" data-x-data-mw-someext="baz" data-ok="fred" data-x-data-object-id="123" data-parsoid='{"stx":"html","a":{"data-ooui":null,"data-bad:ns":null},"sa":{"data-ooui":"xyzzy","data-bad:ns":"ns"}}'>d</div>
!! end
!! test
!! html/parsoid
<p><a rel="mw:WikiLink" href="./User:+%25" title="User:+%" data-parsoid='{"stx":"simple","a":{"href":"./User:+%25"},"sa":{"href":"User:+%"}}'>User:+%</a> <a rel="mw:WikiLink" href="./Page+title%25" title="Page+title%" data-parsoid='{"stx":"simple","a":{"href":"./Page+title%25"},"sa":{"href":"Page+title%"}}'>Page+title%</a>
<a rel="mw:WikiLink" href="./%25+" title="%+" data-parsoid='{"stx":"simple","a":{"href":"./%25+"},"sa":{"href":"%+"}}'>%+</a> <a rel="mw:WikiLink" href="./%25+" title="%+" data-parsoid='{"stx":"piped","a":{"href":"./%25+"},"sa":{"href":"%+"}}'>%20</a> <a rel="mw:WikiLink" href="./%25+" title="%+" data-parsoid='{"stx":"simple","a":{"href":"./%25+"},"sa":{"href":"%+ "}}'>%+ </a> <a rel="mw:WikiLink" href="./%25+r" title="%+r" data-parsoid='{"stx":"simple","a":{"href":"./%25+r"},"sa":{"href":"%+r"}}'>%+r</a>
-<a rel="mw:WikiLink" href="./%25" title="%" data-parsoid='{"stx":"simple","a":{"href":"./%25"},"sa":{"href":"%"}}'>%</a> <a rel="mw:WikiLink" href="./+" title="+" data-parsoid='{"stx":"simple","a":{"href":"./+"},"sa":{"href":"+"}}'>+</a> <figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-parsoid='{"optList":[{"ck":"bogus","ak":"foo"},{"ck":"caption","ak":"[[bar]]"}]}' data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}],"caption":"<a rel=\"mw:WikiLink\" href=\"./Bar\" title=\"Bar\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Bar\"},\"sa\":{\"href\":\"bar\"},\"dsr\":[94,101,2,2]}'>bar</a>"}'><a href="./File:%25+abc9" data-parsoid='{"a":{"href":"./File:%25+abc9"},"sa":{}}'><img resource="./File:%25+abc9" src="./Special:FilePath/%25+abc9" height="220" width="220" data-parsoid='{"a":{"resource":"./File:%25+abc9","height":"220","width":"220"},"sa":{"resource":"File:%+abc%39"}}'/></a></figure-inline>
+<a rel="mw:WikiLink" href="./%25" title="%" data-parsoid='{"stx":"simple","a":{"href":"./%25"},"sa":{"href":"%"}}'>%</a> <a rel="mw:WikiLink" href="./+" title="+" data-parsoid='{"stx":"simple","a":{"href":"./+"},"sa":{"href":"+"}}'>+</a> <figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-parsoid='{"optList":[{"ck":"bogus","ak":"foo"},{"ck":"caption","ak":"[[bar]]"}]}' data-mw='{"caption":"<a rel=\"mw:WikiLink\" href=\"./Bar\" title=\"Bar\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Bar\"},\"sa\":{\"href\":\"bar\"},\"dsr\":[94,101,2,2]}'>bar</a>","errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/%25+abc9"><span resource="./File:%25+abc9" data-parsoid='{"a":{"resource":"./File:%25+abc9"},"sa":{"resource":"File:%+abc%39"}}'>File:%+abc9</span></a></figure-inline>
<a rel="mw:WikiLink" href="./3E" title="3E" data-parsoid='{"stx":"simple","a":{"href":"./3E"},"sa":{"href":"%33%45"}}'>3E</a> <a rel="mw:WikiLink" href="./3E+" title="3E+" data-parsoid='{"stx":"simple","a":{"href":"./3E+"},"sa":{"href":"%33%45+"}}'>3E+</a></p>
!! end
<a href="/index.php?title=Special:Upload&wpDestFile=Does_not_exist.jpg" class="new" title="File:Does not exist.jpg">Title with & ampersand</a>
</p>
!! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./File:Contains_&_ampersand.jpg"><img resource="./File:Contains_&_ampersand.jpg" src="./Special:FilePath/Contains_&_ampersand.jpg" height="220" width="220"/></a></figure-inline>
-<figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}],"caption":"Title with &amp; ampersand"}'><a href="./File:Does_not_exist.jpg"><img resource="./File:Does_not_exist.jpg" src="./Special:FilePath/Does_not_exist.jpg" height="220" width="220"/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Contains_&_ampersand.jpg"><span resource="./File:Contains_&_ampersand.jpg" data-parsoid='{"a":{"resource":"./File:Contains_&_ampersand.jpg"},"sa":{"resource":"File:Contains & ampersand.jpg"}}'>File:Contains & ampersand.jpg</span></a></figure-inline>
+<figure-inline class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"caption":"Title with &amp; ampersand","errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'><a href="./Special:FilePath/Does_not_exist.jpg"><span resource="./File:Does_not_exist.jpg" data-parsoid='{"a":{"resource":"./File:Does_not_exist.jpg"},"sa":{"resource":"File:Does not exist.jpg"}}'>File:Does not exist.jpg</span></a></figure-inline></p>
!! end
!! test
!! html/parsoid
<p><b>foo</b></p><b><figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure></b><p><b>bar</b></p>
-<small><figure class="mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="34" width="300"/></a></figure></small>
+<small><figure class="mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="34" width="300"/></a><figcaption></figcaption></figure></small>
!! end
!! test
!! html/php+tidy
<b><small><div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg" decoding="async" width="300" height="34" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/450px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/600px-Foobar.jpg 2x" /></a></div></small></b>
!! html/parsoid
-<b><small><figure class="mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="34" width="300"/></a></figure></small></b>
+<b><small><figure class="mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="34" width="300"/></a><figcaption></figcaption></figure></small></b>
!! end
#### ----------------------------------------------------------------
<h2>=foo=</h2>
<h3>=foo=</h3>
-<h1 data-parsoid=''>=foo=</h1>
-<h2 data-parsoid=''>=foo=</h2>
-<h3 data-parsoid=''>=foo=</h3>
-<h4 data-parsoid=''>=foo=</h4>
-<h5 data-parsoid=''>=foo=</h5>
-<h6 data-parsoid=''>=foo=</h6>
+<h1 data-parsoid='{}'>=foo=</h1>
+<h2 data-parsoid='{}'>=foo=</h2>
+<h3 data-parsoid='{}'>=foo=</h3>
+<h4 data-parsoid='{}'>=foo=</h4>
+<h5 data-parsoid='{}'>=foo=</h5>
+<h6 data-parsoid='{}'>=foo=</h6>
!! wikitext
= =foo= =
[[Foo|x <nowiki>[http://google.com g]</nowiki> x]]
[[Foo|<nowiki>[[Bar]]</nowiki>]]
[[Foo|<nowiki>x [[Bar]] x</nowiki>]]
-[[Foo|<nowiki>|Bar</nowiki>]]
+[[Foo||Bar]]
[[Foo|<nowiki>]]bar</nowiki>]]
[[Foo|<nowiki>[[bar</nowiki>]]
[[Foo|<nowiki>x [[ y</nowiki>]]
!! end
# Parsoid only for T66747
+# (Also core doesn't define {{#if}} in default install)
!! test
Properly encapsulate empty-content transclusions in fosterable positions
!! wikitext
!! test
Image: Modifying alt attribute of an image (T58400)
!! options
+disabled
parsoid={
"modes": ["wt2wt"],
"changes": [
456
!! html/parsoid
<p>123</p>
-<figure class="mw-halign-right" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/150px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="17" width="150"/></a></figure>
+<figure class="mw-halign-right" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/150px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="17" width="150"/></a><figcaption></figcaption></figure>
<p>456</p>
!! end
456
!! html/parsoid
<p>123</p>
-<figure class="mw-halign-right" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"right","ak":"right"},{"ck":"thumbnail","ak":"thumb"},{"ck":"width","ak":"150x150px"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/150px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="17" width="150" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"17","width":"150"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></figure>
+<figure class="mw-halign-right" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"right","ak":"right"},{"ck":"thumbnail","ak":"thumb"},{"ck":"width","ak":"150x150px"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/150px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="17" width="150" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"17","width":"150"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption></figcaption></figure>
<p>456</p>
!! end
<p><a href="/wiki/File:Foobar.jpg" class="image" title="link=<"><img alt="link=<" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" /></a>
</p>
!! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"link","ak":"link=<"}]}' data-mw='{"caption":"link=&lt;"}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{}}'><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"link","ak":"link=<"}]}' data-mw='{"attribs":[["link",{"txt":"<"}]]}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
!! end
!! test
</p><p><a href="http://en.wikipedia.org/wiki/Foo" title="caption"><img alt="wikipedia:Foo" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" /></a>
</p>
!! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"caption"}'><a href="./Main_Page" data-parsoid='{"a":{"href":"./Main_Page"},"sa":{"href":"link=[[Main Page]]"}}'><img alt="Main Page" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"alt":"Main Page","resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"alt":"alt=[[Main Page]]","resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Image mw:ExpandedAttrs" about="#mwt1" data-mw='{"attribs":[["alt",{"html":"alt=<a rel=\"mw:WikiLink\" href=\"./Main_Page\" title=\"Main Page\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Main_Page\"},\"sa\":{\"href\":\"Main Page\"},\"dsr\":[41,216,2,2]}'>Main Page</a>","txt":"Main Page"}]],"caption":"caption"}'><a href="./Main_Page" data-parsoid='{"a":{"href":"./Main_Page"},"sa":{"href":"link=[[Main Page]]"}}'><img alt="Main Page" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
-<p><figure-inline class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"caption"}'><a href="./Media:Thumb.png" data-parsoid='{"a":{"href":"./Media:Thumb.png"},"sa":{"href":"link=[[Media:Thumb.png]]"}}'><img alt="Media:Thumb.png" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"alt":"Media:Thumb.png","resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"alt":"alt=[[Media:Thumb.png]]","resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Image mw:ExpandedAttrs" about="#mwt3" data-mw='{"attribs":[["alt",{"html":"alt=<a rel=\"mw:MediaLink\" href=\"//example.com/images/e/ea/Thumb.png\" resource=\"./Media:Thumb.png\" title=\"Thumb.png\" data-parsoid='{\"a\":{\"resource\":\"./Media:Thumb.png\"},\"sa\":{\"resource\":\"Media:Thumb.png\"},\"dsr\":[113,216,null,null]}'>Media:Thumb.png</a>","txt":"Media:Thumb.png"}]],"caption":"caption"}'><a href="./Media:Thumb.png" data-parsoid='{"a":{"href":"./Media:Thumb.png"},"sa":{"href":"link=[[Media:Thumb.png]]"}}'><img alt="Media:Thumb.png" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
-<p><figure-inline class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"caption"}'><a href="http://en.wikipedia.org/wiki/Foo" data-parsoid='{"a":{"href":"http://en.wikipedia.org/wiki/Foo"},"sa":{"href":"link=[[wikipedia:Foo]]"}}'><img alt="wikipedia:Foo" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"alt":"wikipedia:Foo","resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"alt":"alt=[[wikipedia:Foo]]","resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Image mw:ExpandedAttrs" about="#mwt2" data-mw='{"attribs":[["alt",{"html":"alt=<a rel=\"mw:WikiLink/Interwiki\" href=\"http://en.wikipedia.org/wiki/Foo\" title=\"wikipedia:Foo\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"http://en.wikipedia.org/wiki/Foo\"},\"sa\":{\"href\":\"wikipedia:Foo\"},\"isIW\":true,\"dsr\":[189,216,2,2]}'>wikipedia:Foo</a>","txt":"wikipedia:Foo"}]],"caption":"caption"}'><a href="http://en.wikipedia.org/wiki/Foo" data-parsoid='{"a":{"href":"http://en.wikipedia.org/wiki/Foo"},"sa":{"href":"link=[[wikipedia:Foo]]"}}'><img alt="wikipedia:Foo" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
!! end
!! test
|}
!! end
+## Don't necessarily expect this to roundtrip, but run serialization to catch crashers
+!! test
+File in link scenarios
+!! options
+parsoid={
+ "modes": ["wt2html","html2wt"],
+ "suppressErrors": true
+}
+!! wikitext
+[http://www.google.com [[File:Foobar.jpg|123]]]
+
+[http://www.google.com [[File:Foobar.jpg|thumb|123]]]
+!! html/php+tidy
+<p><a rel="nofollow" class="external text" href="http://www.google.com"></a><a href="/wiki/File:Foobar.jpg" class="image" title="123"><img alt="123" src="http://example.com/images/3/3a/Foobar.jpg" decoding="async" width="1941" height="220" /></a>
+</p>
+<a rel="nofollow" class="external text" href="http://www.google.com"></a><div class="thumb tright"><a rel="nofollow" class="external text" href="http://www.google.com"></a><div class="thumbinner" style="width:182px;"><a rel="nofollow" class="external text" href="http://www.google.com"></a><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" decoding="async" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>123</div></div></div>
+!! html/parsoid
+<p><a rel="mw:ExtLink" class="external text" href="http://www.google.com" data-parsoid='{"targetOff":23,"contentOffsets":[23,46]}'><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"123"}]}' data-mw='{"caption":"123"}'></figure-inline></a><a href="./File:Foobar.jpg" data-parsoid='{"misnested":true}'><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"File:Foobar.jpg"},"misnested":true}'/></a></p>
+
+<a rel="mw:ExtLink" class="external autonumber" href="http://www.google.com" data-parsoid='{"targetOff":72,"contentOffsets":[72,101]}'></a><figure class="mw-default-size" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"caption","ak":"123"}]}'><a rel="mw:ExtLink" class="external autonumber" href="http://www.google.com" data-parsoid='{"targetOff":72,"contentOffsets":[72,101]}'></a><a href="./File:Foobar.jpg" data-parsoid='{"misnested":true}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"resource":"File:Foobar.jpg"},"misnested":true}'/></a><figcaption data-parsoid='{"misnested":true}'>123</figcaption></figure>
+!! end
+
# --------------------------------------------
# Tests spec'ing wikitext serialization norms |
# --------------------------------------------
!! html/php+tidy
<div class="thumb tright"><div class="thumbinner" style="width:137px;"><a href="/wiki/File:Thumb.png" class="image"><img alt="Thumb.png" src="http://example.com/images/e/ea/Thumb.png" decoding="async" width="135" height="135" class="thumbimage" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Thumb.png" class="internal" title="Enlarge"></a></div></div></div></div>
!! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Thumb.png"><img resource="./File:Thumb.png" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></a></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Thumb.png"><img resource="./File:Thumb.png" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></a><figcaption></figcaption></figure>
!! end
!! test
[[stats:v2/#/fr.wikipedia.org/reading/page-views-by-country/normal%7Cmap%7C2-Year~2016060100~2018071100%7C~total|10]]
!! end
+## FIXME: "gerrit" isn't in PHP's setupInterwikis
+!! test
+T199926: Hash only interwiki link
+!! wikitext
+[[meatball:Test#1/2]]
+[[gerrit:#/q/project:mediawiki/services/parsoid|Gerrit]]
+!! html/php+tidy
+<p><a href="http://www.usemod.com/cgi-bin/mb.pl?Test#1.2F2" class="extiw" title="meatball:Test">meatball:Test#1/2</a>
+<a href="/index.php?title=Gerrit:&action=edit&redlink=1" class="new" title="Gerrit: (page does not exist)">Gerrit</a>
+</p>
+!! html/parsoid
+<p><a rel="mw:WikiLink/Interwiki" href="http://www.usemod.com/cgi-bin/mb.pl?Test#1.2F2" title="meatball:Test" data-parsoid='{"stx":"simple","a":{"href":"http://www.usemod.com/cgi-bin/mb.pl?Test#1.2F2"},"sa":{"href":"meatball:Test#1/2"},"isIW":true}'>meatball:Test#1/2</a>
+<a rel="mw:WikiLink/Interwiki" href="https://gerrit.wikimedia.org/#/q/project:mediawiki/services/parsoid">Gerrit</a></p>
+!! end
+
!! test
T179544: {{anchorencode:}} output should be always usable in links
!! config
!! test
Section wrapping for well-nested sections (no leading content)
!! options
+notoc
parsoid={
"wrapSections": true
}
=3=
f
+!! html/php+tidy
+
+<h1><span class="mw-headline" id="1">1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: 1">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>a
+</p>
+<h1><span class="mw-headline" id="2">2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: 2">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>b
+</p>
+<h2><span class="mw-headline" id="2.1">2.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: 2.1">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<p>c
+</p>
+<h2><span class="mw-headline" id="2.2">2.2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: 2.2">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<p>d
+</p>
+<h3><span class="mw-headline" id="2.2.1">2.2.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: 2.2.1">edit</a><span class="mw-editsection-bracket">]</span></span></h3>
+<p>e
+</p>
+<h1><span class="mw-headline" id="3">3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: 3">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>f
+</p>
!! html/parsoid
-<section data-mw-section-id="0"></section><section data-mw-section-id="1"><h1 id="1">1</h1>
+<section data-mw-section-id="0"></section><section data-mw-section-id="1"><h1 id="1" data-parsoid="{}">1</h1>
<p>a</p>
-</section><section data-mw-section-id="2"><h1 id="2">2</h1>
+</section><section data-mw-section-id="2"><h1 id="2" data-parsoid="{}">2</h1>
<p>b</p>
-<section data-mw-section-id="3"><h2 id="2.1">2.1</h2>
+<section data-mw-section-id="3"><h2 id="2.1" data-parsoid="{}">2.1</h2>
<p>c</p>
-</section><section data-mw-section-id="4"><h2 id="2.2">2.2</h2>
+</section><section data-mw-section-id="4"><h2 id="2.2" data-parsoid="{}">2.2</h2>
<p>d</p>
-<section data-mw-section-id="5"><h3 id="2.2.1">2.2.1</h3>
+<section data-mw-section-id="5"><h3 id="2.2.1" data-parsoid="{}">2.2.1</h3>
<p>e</p>
-</section></section></section><section data-mw-section-id="6"><h1 id="3">3</h1>
+</section></section></section><section data-mw-section-id="6"><h1 id="3" data-parsoid="{}">3</h1>
<p>f</p>
</section>
!! test
Section wrapping for well-nested sections (with leading content)
!! options
+notoc
parsoid={
"wrapSections": true
}
==2.1==
c
+!! html/php+tidy
+<p>Para 1.
+</p><p>
+Para 2 with a </p><div>nested in it</div>
+<p>Para 3.
+</p>
+<h1><span class="mw-headline" id="1">1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: 1">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>a
+</p>
+<h1><span class="mw-headline" id="2">2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: 2">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>b
+</p>
+<h2><span class="mw-headline" id="2.1">2.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: 2.1">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<p>c
+</p>
!! html/parsoid
<section data-mw-section-id="0"><p>Para 1.</p>
<p>Para 3.</p>
-</section><section data-mw-section-id="1"><h1 id="1">1</h1>
+</section><section data-mw-section-id="1"><h1 id="1" data-parsoid="{}">1</h1>
<p>a</p>
-</section><section data-mw-section-id="2"><h1 id="2">2</h1>
+</section><section data-mw-section-id="2"><h1 id="2" data-parsoid="{}">2</h1>
<p>b</p>
-<section data-mw-section-id="3"><h2 id="2.1">2.1</h2>
+<section data-mw-section-id="3"><h2 id="2.1" data-parsoid="{}">2.1</h2>
<p>c</p>
</section></section>
!! test
Section wrapping with template-generated sections (good nesting 1)
!! options
+notoc
parsoid={
"wrapSections": true
}
==1.1==
b
}}
-
==1.2==
c
=2=
d
+!! html/php+tidy
+
+<h1><span class="mw-headline" id="1">1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: 1">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>a
+</p>
+<h2><span class="mw-headline" id="1.1">1.1</span></h2>
+<p>b
+</p>
+<h2><span class="mw-headline" id="1.2">1.2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: 1.2">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<p>c
+</p>
+<h1><span class="mw-headline" id="2">2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: 2">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>d
+</p>
!! html/parsoid
-<section data-mw-section-id="0"></section><section data-mw-section-id="1"><h1 id="1">1</h1>
+<section data-mw-section-id="0"></section><section data-mw-section-id="1"><h1 id="1" data-parsoid="{}">1</h1>
<p>a</p>
<section data-mw-section-id="-1"><h2 about="#mwt1" typeof="mw:Transclusion" id="1.1" data-parsoid='{"dsr":[9,33,null,null],"pi":[[{"k":"1","named":true,"spc":["","","\n","\n"]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"==1.1==\nb"}},"i":0}}]}'>1.1</h2><span about="#mwt1">
</span><p about="#mwt1">b</p>
-</section><section data-mw-section-id="3"><h2 id="1.2">1.2</h2>
+</section><section data-mw-section-id="3"><h2 id="1.2" data-parsoid="{}">1.2</h2>
<p>c</p>
-</section></section><section data-mw-section-id="4"><h1 id="2">2</h1>
+</section></section><section data-mw-section-id="4"><h1 id="2" data-parsoid="{}">2</h1>
<p>d</p></section>
!! end
!! test
Section wrapping with template-generated sections (good nesting 2)
!! options
+notoc
parsoid={
"wrapSections": true,
"modes": ["wt2html", "wt2wt"]
}}
=2=
e
+!! html/php+tidy
+
+<h1><span class="mw-headline" id="1">1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: 1">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>a
+</p>
+<h2><span class="mw-headline" id="1.1">1.1</span></h2>
+<p>b
+</p>
+<h3><span class="mw-headline" id="1.1.1">1.1.1</span></h3>
+<p>d
+</p>
+<h1><span class="mw-headline" id="2">2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: 2">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>e
+</p>
!! html/parsoid
<section data-mw-section-id="0"></section><section data-mw-section-id="1"><h1 id="1">1</h1>
<p>a</p>
!! test
Section wrapping with template-generated sections (good nesting 3)
!! options
+notoc
parsoid={
"wrapSections": true,
"modes": ["wt2html", "wt2wt"]
}}
=2=
e
+!! html/php+tidy
+
+<h1><span class="mw-headline" id="1">1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: 1">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>a
+</p><p>x
+</p>
+<h2><span class="mw-headline" id="1.1">1.1</span></h2>
+<p>b
+</p>
+<h2><span class="mw-headline" id="1.2">1.2</span></h2>
+<p>c
+</p>
+<h3><span class="mw-headline" id="1.2.1">1.2.1</span></h3>
+<p>d
+</p>
+<h1><span class="mw-headline" id="2">2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: 2">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>e
+</p>
!! html/parsoid
<section data-mw-section-id="0"></section><section data-mw-section-id="1" data-parsoid="{}"><h1 id="1"> 1 </h1>
<p>a</p>
!! test
Section wrapping with template-generated sections (bad nesting 1)
!! options
+notoc
parsoid={
"wrapSections": true
}
<div>
a
-{{echo|
+{{echo|1=
=1=
b
}}
c
</div>
+!! html/php+tidy
+<div>
+<p>a
+</p>
+<h1><span class="mw-headline" id="1">1</span></h1>
+<p>b
+</p><p>c
+</p>
+</div>
!! html/parsoid
<section data-mw-section-id="-1"></section><section data-mw-section-id="-2"><div data-parsoid='{"stx":"html"}'>
<p>a</p>
-<span about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"\n=1=\nb\n"}},"i":0}},"\n\nc\n"]}'>
-</span><section data-mw-section-id="-1" about="#mwt1"><h1 about="#mwt1" id="1">1</h1><span about="#mwt1">
-</span><p about="#mwt1">b
-</p><span about="#mwt1">
+<section data-mw-section-id="-1"><h1 about="#mwt1" typeof="mw:Transclusion" id="1" data-parsoid='{"pi":[[{"k":"1","named":true,"spc":["","","\n","\n"]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"=1=\nb"}},"i":0}}]}'>1</h1><span about="#mwt1">
+</span><p about="#mwt1">b</p>
-</span><p about="#mwt1">c</p><span about="#mwt1">
-</span></section></div></section>
+<p>c</p>
+</section></div></section>
!! end
# Because of section-wrapping and template-wrapping interactions,
!! test
Section wrapping with template-generated sections (bad nesting 2)
!! options
+notoc
parsoid={
"wrapSections": true
}
=3=
e
+!! html/php+tidy
+
+<h1><span class="mw-headline" id="1">1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: 1">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>a
+</p>
+<h1><span class="mw-headline" id="2">2</span></h1>
+<p>b
+</p>
+<h2><span class="mw-headline" id="2.1">2.1</span></h2>
+<p>c
+</p><p>d
+</p>
+<h1><span class="mw-headline" id="3">3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: 3">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>e
+</p>
!! html/parsoid
-<section data-mw-section-id="0"></section><section data-mw-section-id="1"><h1 id="1">1</h1>
+<section data-mw-section-id="0"></section><section data-mw-section-id="1"><h1 id="1" data-parsoid="{}">1</h1>
<p>a</p>
</section><section data-mw-section-id="-1"><h1 about="#mwt1" typeof="mw:Transclusion" id="2" data-parsoid='{"dsr":[9,45,null,null],"pi":[[{"k":"1","named":true,"spc":["","","\n","\n"]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"=2=\nb\n==2.1==\nc"}},"i":0}},"\n\nd\n\n"]}'>2</h1><span about="#mwt1">
</span><p about="#mwt1">d</p><span about="#mwt1">
-</span></section></section><section data-mw-section-id="4"><h1 id="3">3</h1>
+</span></section></section><section data-mw-section-id="4"><h1 id="3" data-parsoid="{}">3</h1>
<p>e</p></section>
!! end
!! test
Section wrapping with template-generated sections (bad nesting 3)
!! options
+notoc
parsoid={
"wrapSections": true,
"modes": ["wt2html", "wt2wt"]
=3=
e
+!! html/php+tidy
+
+<h1><span class="mw-headline" id="1">1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: 1">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>a
+</p>
+<h2><span class="mw-headline" id="1.2">1.2</span></h2>
+<p>b
+</p>
+<h1><span class="mw-headline" id="2">2</span></h1>
+<p>c
+</p><p>d
+</p>
+<h1><span class="mw-headline" id="3">3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: 3">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>e
+</p>
!! html/parsoid
<section data-mw-section-id="0"></section><section data-mw-section-id="1" about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":["=1=\na\n\n",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"==1.2==\nb\n=2=\nc"}},"i":0}},"\n\nd\n\n"]}'><h1 id="1">1</h1>
<p>a</p>
!! test
Section wrapping with uneditable lead section + div wrapping multiple sections
!! options
+notoc
parsoid={
"wrapSections": true
}
==3.1==
e
+!! html/php+tidy
+<p>foo
+</p>
+<div style="border:1px solid red;">
+
+<h1><span class="mw-headline" id="1">1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: 1">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>a
+</p>
+<h2><span class="mw-headline" id="1.1">1.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: 1.1">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<p>b
+</p>
+<h1><span class="mw-headline" id="2">2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: 2">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>c
+</p>
+</div>
+<h1><span class="mw-headline" id="3">3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: 3">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>d
+</p>
+<h2><span class="mw-headline" id="3.1">3.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: 3.1">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<p>e
+</p>
!! html/parsoid
<section data-mw-section-id="-1"><p>foo</p>
</section><section data-mw-section-id="-2"><div style="border:1px solid red;">
-<section data-mw-section-id="1"><h1 id="1">1</h1>
+<section data-mw-section-id="1"><h1 id="1" data-parsoid="{}">1</h1>
<p>a</p>
-<section data-mw-section-id="2"><h2 id="1.1">1.1</h2>
+<section data-mw-section-id="2"><h2 id="1.1" data-parsoid="{}">1.1</h2>
<p>b</p>
-</section></section><section data-mw-section-id="-1"><h1 id="2">2</h1>
+</section></section><section data-mw-section-id="-1"><h1 id="2" data-parsoid="{}">2</h1>
<p>c</p>
</section></div>
-</section><section data-mw-section-id="4"><h1 id="3">3</h1>
+</section><section data-mw-section-id="4"><h1 id="3" data-parsoid="{}">3</h1>
<p>d</p>
-<section data-mw-section-id="5"><h2 id="3.1">3.1</h2>
+<section data-mw-section-id="5"><h2 id="3.1" data-parsoid="{}">3.1</h2>
<p>e</p>
</section></section>
!! end
!! test
Section wrapping with editable lead section + div overlapping multiple sections
!! options
+notoc
parsoid={
"wrapSections": true
}
==3.1==
g
+!! html/php+tidy
+<p>foo
+</p>
+
+<h1><span class="mw-headline" id="1">1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: 1">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>a
+</p>
+<div style="border:1px solid red;">
+<p>b
+</p>
+<h2><span class="mw-headline" id="1.1">1.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: 1.1">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<p>c
+</p>
+<h1><span class="mw-headline" id="2">2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: 2">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>d
+</p>
+</div>
+<p>e
+</p>
+<h1><span class="mw-headline" id="3">3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: 3">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>f
+</p>
+<h2><span class="mw-headline" id="3.1">3.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: 3.1">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<p>g
+</p>
!! html/parsoid
<section data-mw-section-id="0"><p>foo</p>
-</section><section data-mw-section-id="-1"><h1 id="1">1</h1>
+</section><section data-mw-section-id="-1"><h1 id="1" data-parsoid="{}">1</h1>
<p>a</p>
</section><section data-mw-section-id="-2"><div style="border:1px solid red;">
<p>b</p>
-<section data-mw-section-id="2"><h2 id="1.1">1.1</h2>
+<section data-mw-section-id="2"><h2 id="1.1" data-parsoid="{}">1.1</h2>
<p>c</p>
-</section><section data-mw-section-id="-1"><h1 id="2">2</h1>
+</section><section data-mw-section-id="-1"><h1 id="2" data-parsoid="{}">2</h1>
<p>d</p>
</section></div>
<p>e</p>
-</section><section data-mw-section-id="4"><h1 id="3">3</h1>
+</section><section data-mw-section-id="4"><h1 id="3" data-parsoid="{}">3</h1>
<p>f</p>
-<section data-mw-section-id="5"><h2 id="3.1">3.1</h2>
+<section data-mw-section-id="5"><h2 id="3.1" data-parsoid="{}">3.1</h2>
<p>g</p>
</section></section>
!! end
!! test
HTML header tags should not be wrapped in section tags
!! options
+notoc
parsoid={
"wrapSections": true
}
<h1>c</h1>
=d=
+!! html/php+tidy
+<p>foo
+</p>
+
+<h1><span class="mw-headline" id="a">a</span></h1>
+<h1><span class="mw-headline" id="b">b</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: b">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<h1><span class="mw-headline" id="c">c</span></h1>
+<h1><span class="mw-headline" id="d">d</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: d">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
!! html/parsoid
<section data-mw-section-id="0"><p>foo</p>
<h1 id="a" data-parsoid='{"stx":"html"}'>a</h1>
-</section><section data-mw-section-id="1"><h1 id="b">b</h1>
+</section><section data-mw-section-id="1"><h1 id="b" data-parsoid="{}">b</h1>
<h1 id="c" data-parsoid='{"stx":"html"}'>c</h1>
-</section><section data-mw-section-id="2"><h1 id="d">d</h1></section>
+</section><section data-mw-section-id="2"><h1 id="d" data-parsoid="{}">d</h1></section>
!! end
!! test
Lead section containing only whitespace and comments.
!! options
+notoc
parsoid={
"wrapSections": true
}
=2=
b
+!! html/php+tidy
+<h1><span class="mw-headline" id="1">1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: 1">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>a
+</p>
+<h1><span class="mw-headline" id="2">2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: 2">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
+<p>b
+</p>
!! html/parsoid
<section data-mw-section-id="0" data-parsoid="{}">
<!-- this is a comment, presumably significant to editors -->
-</section><section data-mw-section-id="1"><h1 id="1">1</h1>
+</section><section data-mw-section-id="1"><h1 id="1" data-parsoid="{}">1</h1>
<p>a</p>
-</section><section data-mw-section-id="2"><h1 id="2">2</h1>
-<p>b</p></section>
+</section><section data-mw-section-id="2"><h1 id="2" data-parsoid="{}">2</h1>
+<p>b</p>
+</section>
!! end
!! test
-Pseudo-sections emitted by templates should have id -2
+Pseudo-sections emitted by templates should have id -2
!! options
+notoc
parsoid={
"wrapSections": true
}
==b==
</div>
}}
+!! html/php+tidy
+<p>foo
+</p>
+<div>
+<h2><span class="mw-headline" id="a">a</span></h2>
+<h2><span class="mw-headline" id="b">b</span></h2>
+</div>
!! html/parsoid
<section data-mw-section-id="-1"><p>foo</p>
</section><section data-mw-section-id="-2"><div about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"stx":"html","pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"<div>\n==a==\n==b==\n</div>\n"}},"i":0}}]}'>
</span></section>
!! end
+!! test
+T213468: Transcluded sections don't get PHP section numbers
+!! options
+notoc
+parsoid={
+ "wrapSections": true
+}
+!! wikitext
+==PHP section=1==
+{{echo|1=
+== This is counted as if it were section 2 ==
+}}
+==PHP section=3==
+!! html/php+tidy
+<h2><span class="mw-headline" id="PHP_section.3D1">PHP section=1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: PHP section=1">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<h2><span class="mw-headline" id="This_is_counted_as_if_it_were_section_2">This is counted as if it were section 2</span></h2>
+<h2><span class="mw-headline" id="PHP_section.3D3">PHP section=3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: PHP section=3">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+!! html/parsoid
+<section data-mw-section-id="0"></section><section data-mw-section-id="1"><h2 id="PHP_section=1" data-parsoid="{}"><span id="PHP_section.3D1" typeof="mw:FallbackId"></span>PHP section=1</h2>
+</section><section data-mw-section-id="-1"><h2 about="#mwt1" typeof="mw:Transclusion" id="This_is_counted_as_if_it_were_section_2" data-parsoid='{"pi":[[{"k":"1","named":true,"spc":["","","\n","\n"]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"== This is counted as if it were section 2 =="}},"i":0}}]}'>This is counted as if it were section 2</h2>
+</section><section data-mw-section-id="3"><h2 id="PHP_section=3" data-parsoid="{}"><span id="PHP_section.3D3" typeof="mw:FallbackId"></span>PHP section=3</h2></section>
+!! end
+
+!! test
+T213468: Corner cases in edit section ID assignment in tokenizer
+!! options
+notoc
+parsoid={
+ "wrapSections": true
+}
+!! wikitext
+==PHP section=1==
+{{echo|Not a section|
+== This is counted as if it were section 2 ==
+}}
+==PHP section=3==
+{{echo3|1=
+== This is counted as if it were section 4 ==
+}}
+==PHP section=5==
+{{#tag:p|Not a section|data-ignored=
+== This is counted as if it were section 6 ==
+}}
+==PHP section=7==
+{{echo|1=Not a ==heading==}}
+==PHP section=8==
+[[File:Foobar.jpg|thumb|
+==This is section 9, even though it's in a caption==
+]]
+==PHP section=10==
+!! html/php+tidy
+
+<h2><span class="mw-headline" id="PHP_section.3D1">PHP section=1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: PHP section=1">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<p>Not a section
+</p>
+<h2><span class="mw-headline" id="PHP_section.3D3">PHP section=3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: PHP section=3">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<h2><span class="mw-headline" id="This_is_counted_as_if_it_were_section_4">This is counted as if it were section 4</span></h2>
+<h2><span class="mw-headline" id="This_is_counted_as_if_it_were_section_4_2">This is counted as if it were section 4</span></h2>
+<h2><span class="mw-headline" id="This_is_counted_as_if_it_were_section_4_3">This is counted as if it were section 4</span></h2>
+<h2><span class="mw-headline" id="PHP_section.3D5">PHP section=5</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: PHP section=5">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<p data-ignored="== This is counted as if it were section 6 ==">Not a section</p>
+<h2><span class="mw-headline" id="PHP_section.3D7">PHP section=7</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=7" title="Edit section: PHP section=7">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<p>Not a ==heading==
+</p>
+<h2><span class="mw-headline" id="PHP_section.3D8">PHP section=8</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=8" title="Edit section: PHP section=8">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" decoding="async" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div><h2><span class="mw-headline" id="This_is_section_9.2C_even_though_it.27s_in_a_caption">This is section 9, even though it's in a caption</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=9" title="Edit section: This is section 9, even though it's in a caption">edit</a><span class="mw-editsection-bracket">]</span></span></h2></div></div></div>
+<h2><span class="mw-headline" id="PHP_section.3D10">PHP section=10</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=10" title="Edit section: PHP section=10">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+!! html/parsoid
+<section data-mw-section-id="0"></section><section data-mw-section-id="1"><h2 id="PHP_section=1" data-parsoid="{}"><span id="PHP_section.3D1" typeof="mw:FallbackId"></span>PHP section=1</h2>
+<p about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"1"},{"k":"2"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"Not a section"},"2":{"wt":"\n== This is counted as if it were section 2 ==\n"}},"i":0}}]}'>Not a section</p>
+</section><section data-mw-section-id="3"><h2 id="PHP_section=3" data-parsoid="{}"><span id="PHP_section.3D3" typeof="mw:FallbackId"></span>PHP section=3</h2>
+</section><section data-mw-section-id="-1" about="#mwt5" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"1","named":true,"spc":["","","\n","\n"]}]]}' data-mw='{"parts":["",{"template":{"target":{"wt":"echo3","href":"./Template:Echo3"},"params":{"1":{"wt":"== This is counted as if it were section 4 =="}},"i":0}},"\n"]}'><h2 about="#mwt2" typeof="mw:Transclusion" id="This_is_counted_as_if_it_were_section_4" data-parsoid='{"pi":[[{"k":"1","named":true,"spc":["","","\n","\n"]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo3","href":"./Template:Echo3"},"params":{"1":{"wt":"== This is counted as if it were section 4 =="}},"i":0}}]}'>This is counted as if it were section 4</h2><span about="#mwt2">
+</span></section><section data-mw-section-id="-1" about="#mwt5"><h2 about="#mwt2" id="This_is_counted_as_if_it_were_section_4_2">This is counted as if it were section 4</h2><span about="#mwt2">
+</span></section><section data-mw-section-id="-1" about="#mwt5"><h2 about="#mwt2" id="This_is_counted_as_if_it_were_section_4_3">This is counted as if it were section 4</h2>
+</section><section data-mw-section-id="5"><h2 id="PHP_section=5" data-parsoid="{}"><span id="PHP_section.3D5" typeof="mw:FallbackId"></span>PHP section=5</h2>
+<p data-ignored=" This is counted as if it were section 6 " about="#mwt3" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"1"},{"k":"data-ignored","named":true,"spc":["","","\n","\n"]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"#tag:p","function":"tag"},"params":{"1":{"wt":"Not a section"},"data-ignored":{"wt":"== This is counted as if it were section 6 =="}},"i":0}}]}'>Not a section</p>
+</section><section data-mw-section-id="7"><h2 id="PHP_section=7" data-parsoid="{}"><span id="PHP_section.3D7" typeof="mw:FallbackId"></span>PHP section=7</h2>
+<p about="#mwt4" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"1","named":true}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"Not a ==heading=="}},"i":0}}]}'>Not a ==heading==</p>
+</section><section data-mw-section-id="8"><h2 id="PHP_section=8" data-parsoid="{}"><span id="PHP_section.3D8" typeof="mw:FallbackId"></span>PHP section=8</h2>
+<figure class="mw-default-size" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"caption","ak":"\n== This is counted as if it were section 9 ==\n"}]}'><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption>
+<section data-mw-section-id="-1"><h2 id="This_is_section_9,_even_though_it's_in_a_caption" data-parsoid="{}"><span id="This_is_section_9.2C_even_though_it.27s_in_a_caption" typeof="mw:FallbackId"></span>This is section 9, even though it's in a caption</h2>
+</section></figcaption></figure>
+</section><section data-mw-section-id="10"><h2 id="PHP_section=10" data-parsoid="{}"><span id="PHP_section.3D10" typeof="mw:FallbackId" data-parsoid='{"dsr":[412,412]}'></span>PHP section=10</h2></section>
+!! end
+
+!! test
+T215628: Section numbering and <includeonly> and <noinclude> on a page
+!! options
+notoc
+parsoid={
+ "wrapSections": true
+}
+!! wikitext
+==PHP section=1==
+<noinclude>
+==PHP section=2==
+</noinclude>
+==PHP section=3==
+<includeonly>
+==This is not counted as section 4==
+</includeonly>
+==PHP section=4==
+!! html/php+tidy
+
+<h2><span class="mw-headline" id="PHP_section.3D1">PHP section=1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: PHP section=1">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<h2><span class="mw-headline" id="PHP_section.3D2">PHP section=2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: PHP section=2">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<h2><span class="mw-headline" id="PHP_section.3D3">PHP section=3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: PHP section=3">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<h2><span class="mw-headline" id="PHP_section.3D4">PHP section=4</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: PHP section=4">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+!! html/parsoid
+PARSOID HAS A BUG HERE: T215628
+!! end
+
##########################################################################
Tests demonstrating white-space insensitivity in input wikitext
for wikitext headings, wikitext list items, and wikitext table captions,
] ],
'revision' => [ 'revision', 'rev_user', 'rev_id', [
'rev_page' => 42,
- 'rev_text_id' => 42,
'rev_len' => 0,
'rev_timestamp' => $db->timestamp(),
] ],
$m->getInsertValuesWithTempTable( $this->db, 'rev_user', $userIdentity );
$extraFields = [
'rev_page' => 42,
- 'rev_text_id' => 42,
'rev_len' => 0,
'rev_timestamp' => $this->db->timestamp(),
] + $cFields;
$overrides['scripts'][] = $this->getSqlPatchPath( $db, 'patch-slot_roles' );
$overrides['scripts'][] = $this->getSqlPatchPath( $db, 'patch-content_models' );
$overrides['scripts'][] = $this->getSqlPatchPath( $db, 'patch-content' );
- $overrides['scripts'][] = $this->getSqlPatchPath( $db, 'patch-slots.sql' );
+ $overrides['scripts'][] = $this->getSqlPatchPath( $db, 'patch-slots' );
}
if ( !$this->hasPreMcrFields( $db ) ) {
namespace MediaWiki\Logger\Monolog;
/**
+ * Flay per https://phabricator.wikimedia.org/T218688.
+ *
+ * @group Broken
* @covers \MediaWiki\Logger\Monolog\CeeFormatter
*/
class CeeFormatterTest extends \PHPUnit\Framework\TestCase {
namespace MediaWiki\Tests\Maintenance;
use DumpBackup;
+use MediaWiki\MediaWikiServices;
+use MediaWikiTestCase;
+use MWException;
use Title;
use WikiExporter;
+use Wikimedia\Rdbms\IDatabase;
+use Wikimedia\Rdbms\LoadBalancer;
use WikiPage;
/**
private $revId4_1, $textId4_1;
private $namespace, $talk_namespace;
+ /**
+ * @var LoadBalancer|null
+ */
+ private $streamingLoadBalancer = null;
+
function addDBData() {
// be sure, titles created here using english namespace names
$this->setContentLang( 'en' );
"Page ids increasing without holes" );
}
+ function tearDown() {
+ parent::tearDown();
+
+ if ( isset( $this->streamingLoadBalancer ) ) {
+ $this->streamingLoadBalancer->closeAll();
+ }
+ }
+
+ /**
+ * Returns a new database connection which is separate from the conenctions returned
+ * by the default LoadBalancer instance.
+ *
+ * @return IDatabase
+ */
+ private function newStreamingDBConnection() {
+ // Create a *new* LoadBalancer, so no connections are shared
+ if ( !$this->streamingLoadBalancer ) {
+ $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+
+ $this->streamingLoadBalancer = $lbFactory->newMainLB();
+ }
+
+ $db = $this->streamingLoadBalancer->getConnection( DB_REPLICA );
+
+ // Make sure the DB connection has the fake table clones and the fake table prefix
+ MediaWikiTestCase::setupDatabaseWithTestPrefix( $db );
+
+ // Make sure the DB connection has all the test data
+ $this->copyTestData( $this->db, $db );
+
+ return $db;
+ }
+
+ /**
+ * @param array $argv
+ * @param int $startId
+ * @param int $endId
+ *
+ * @return DumpBackup
+ */
+ private function newDumpBackup( $argv, $startId, $endId ) {
+ $dumper = new DumpBackup( $argv );
+ $dumper->startId = $startId;
+ $dumper->endId = $endId;
+ $dumper->reporting = false;
+
+ // NOTE: The copyTestData() method used by newStreamingDBConnection()
+ // doesn't work with SQLite (T217607).
+ // But DatabaseSqlite doesn't support streaming anyway, so just skip that part.
+ if ( $this->db->getType() === 'sqlite' ) {
+ $dumper->setDB( $this->db );
+ } else {
+ $dumper->setDB( $this->newStreamingDBConnection() );
+ }
+
+ return $dumper;
+ }
+
function testFullTextPlain() {
// Preparing the dump
$fname = $this->getNewTempFile();
- $dumper = new DumpBackup();
- $dumper->loadWithArgv( [ '--full', '--quiet', '--output', 'file:' . $fname ] );
- $dumper->startId = $this->pageId1;
- $dumper->endId = $this->pageId4 + 1;
- $dumper->setDB( $this->db );
+ $dumper = $this->newDumpBackup(
+ [ '--full', '--quiet', '--output', 'file:' . $fname ],
+ $this->pageId1,
+ $this->pageId4 + 1
+ );
// Performing the dump
$dumper->execute();
// Preparing the dump
$fname = $this->getNewTempFile();
- $dumper = new DumpBackup();
- $dumper->loadWithArgv( [ '--full', '--quiet', '--output', 'file:' . $fname, '--stub' ] );
- $dumper->startId = $this->pageId1;
- $dumper->endId = $this->pageId4 + 1;
- $dumper->setDB( $this->db );
+ $dumper = $this->newDumpBackup(
+ [ '--full', '--quiet', '--output', 'file:' . $fname, '--stub' ],
+ $this->pageId1,
+ $this->pageId4 + 1
+ );
// Performing the dump
$dumper->execute();
// Preparing the dump
$fname = $this->getNewTempFile();
- $dumper = new DumpBackup( [ '--output', 'file:' . $fname ] );
- $dumper->startId = $this->pageId1;
- $dumper->endId = $this->pageId4 + 1;
- $dumper->reporting = false;
- $dumper->setDB( $this->db );
+ $dumper = $this->newDumpBackup(
+ [ '--output', 'file:' . $fname ],
+ $this->pageId1,
+ $this->pageId4 + 1
+ );
// Performing the dump
$dumper->dump( WikiExporter::CURRENT, WikiExporter::STUB );
// Preparing the dump
$fname = $this->getNewTempFile();
- $dumper = new DumpBackup( [ '--output', 'gzip:' . $fname ] );
- $dumper->startId = $this->pageId1;
- $dumper->endId = $this->pageId4 + 1;
- $dumper->reporting = false;
- $dumper->setDB( $this->db );
+ $dumper = $this->newDumpBackup(
+ [ '--output', 'gzip:' . $fname ],
+ $this->pageId1,
+ $this->pageId4 + 1
+ );
// Performing the dump
$dumper->dump( WikiExporter::CURRENT, WikiExporter::STUB );
$fnameMetaCurrent = $this->getNewTempFile();
$fnameArticles = $this->getNewTempFile();
- $dumper = new DumpBackup( [ "--full", "--stub", "--output=gzip:" . $fnameMetaHistory,
- "--output=gzip:" . $fnameMetaCurrent, "--filter=latest",
- "--output=gzip:" . $fnameArticles, "--filter=latest",
- "--filter=notalk", "--filter=namespace:!NS_USER",
- "--reporting=1000" ] );
- $dumper->startId = $this->pageId1;
- $dumper->endId = $this->pageId4 + 1;
- $dumper->setDB( $this->db );
+ $dumper = $this->newDumpBackup(
+ [ "--full", "--stub", "--output=gzip:" . $fnameMetaHistory,
+ "--output=gzip:" . $fnameMetaCurrent, "--filter=latest",
+ "--output=gzip:" . $fnameArticles, "--filter=latest",
+ "--filter=notalk", "--filter=namespace:!NS_USER",
+ "--reporting=1000"
+ ],
+ $this->pageId1,
+ $this->pageId4 + 1
+ );
+ $dumper->reporting = true;
// xmldumps-backup uses reporting. We will not check the exact reported
// message, as they are dependent on the processing power of the used
use ContentHandler;
use FetchText;
+use MediaWiki\Storage\RevisionRecord;
use MediaWikiTestCase;
use MWException;
use Title;
private $fetchText;
/**
- * Adds a revision to a page, while returning the resuting text's id
+ * Adds a revision to a page and returns the main slot's blob address
*
* @param WikiPage $page The page to add the revision to
* @param string $text The revisions text
* @param string $summary The revisions summare
- * @return int
+ * @return string
* @throws MWException
*/
private function addRevision( $page, $text, $summary ) {
if ( $status->isGood() ) {
$value = $status->getValue();
- $revision = $value['revision'];
- $id = $revision->getTextId();
- if ( $id > 0 ) {
- return $id;
- }
+ /** @var RevisionRecord $revision */
+ $revision = $value['revision-record'];
+ $address = $revision->getSlot( 'main' )->getAddress();
+ return $address;
}
- throw new MWException( "Could not determine text id" );
+ throw new MWException( "Could not create revision" );
}
function addDBDataOnce() {
self::$textId2 . "\n23\nFetchTextTestPage2Text1" );
}
+ function testExistingInteger() {
+ $this->assertFilter( (int)preg_replace( '/^tt:/', '', self::$textId2 ),
+ self::$textId2 . "\n23\nFetchTextTestPage2Text1" );
+ }
+
function testExistingSeveral() {
$this->assertFilter(
implode( "\n", [
}
function testNonExisting() {
- $this->assertFilter( self::$textId5 + 10, ( self::$textId5 + 10 ) . "\n-1\n" );
+ \Wikimedia\suppressWarnings();
+ $this->assertFilter( 'tt:77889911', 'tt:77889911' . "\n-1\n" );
+ \Wikimedia\suppressWarnings( true );
+ }
+
+ function testNonExistingInteger() {
+ \Wikimedia\suppressWarnings();
+ $this->assertFilter( '77889911', 'tt:77889911' . "\n-1\n" );
+ \Wikimedia\suppressWarnings( true );
+ }
+
+ function testBadBlobAddressWithColon() {
+ $this->assertFilter( 'foo:bar', 'foo:bar' . "\n-1\n" );
}
function testNegativeInteger() {
- $this->assertFilter( "-42", "-42\n-1\n" );
+ $this->assertFilter( "-42", "tt:-42\n-1\n" );
}
function testFloatingPointNumberExisting() {
- // float -> int -> revision
- $this->assertFilter( self::$textId3 + 0.14159,
+ // float -> int -> address -> revision
+ $id = intval( preg_replace( '/^tt:/', '', self::$textId3 ) ) + 0.14159;
+ $this->assertFilter( 'tt:' . intval( $id ),
self::$textId3 . "\n23\nFetchTextTestPage2Text2" );
}
function testFloatingPointNumberNonExisting() {
- $this->assertFilter( self::$textId5 + 3.14159,
- ( self::$textId5 + 3 ) . "\n-1\n" );
+ \Wikimedia\suppressWarnings();
+ $id = intval( preg_replace( '/^tt:/', '', self::$textId5 ) ) + 3.14159;
+ $this->assertFilter( $id, 'tt:' . intval( $id ) . "\n-1\n" );
+ \Wikimedia\suppressWarnings( true );
}
function testCharacters() {
- $this->assertFilter( "abc", "0\n-1\n" );
+ $this->assertFilter( "abc", "abc\n-1\n" );
}
function testMix() {
- $this->assertFilter( "ab\n" . self::$textId4 . ".5cd\n\nefg\n" . self::$textId2
+ $this->assertFilter( "ab\n" . self::$textId4 . ".5cd\n\nefg\nfoo:bar\n" . self::$textId2
. "\n" . self::$textId3,
implode( "", [
- "0\n-1\n",
- self::$textId4 . "\n23\nFetchTextTestPage2Text3",
- "0\n-1\n",
- "0\n-1\n",
+ "ab\n-1\n",
+ self::$textId4 . ".5cd\n-1\n",
+ "\n-1\n",
+ "efg\n-1\n",
+ "foo:bar\n-1\n",
self::$textId2 . "\n23\nFetchTextTestPage2Text1",
self::$textId3 . "\n23\nFetchTextTestPage2Text2"
] ) );